Repository navigation
Description
背景:为什么现在开这张票
2026-11-09「强制重审」effort(#112 / #113 / PR #114)按事先写死的稳定性闸门撤回:分支两组 ctest -j4 各 9/10、真实 master 同轮数 10/10 全绿,两次失败完全同形态 —— sdk_interaction_tests / PublicPlayer Interactive Paths / test_player_integration.cpp:1408 的 CHECK(afterMonotonic),14.28s / 14.32s、111 断言 110 通过 1 失败、0 SIGSEGV;PR 阶段 Linux 42544814467 与 Windows 42544814456 均 success attempt=1。
撤回决议写明的重做前置条件是「先解决基线假红放大,或拿到 Linux 侧复现 / ASan 证据」。本票落实前者:把这条既有的低概率假红从根上修掉,让 -j4 同轮数对照有干净、可判定的基线,不再出现「分支假红率高于基线」这种无法归因的争议。
历史同源观测:2026-11-08 C1/C5 稳定性对照时 master 9/10 的第 9 轮也报过 sdk_interaction_tests 一次既有 flake(doc/player-state-contract.md §10.4)。基线本身并非无假红,本票要消掉的正是它。
根因假设 H_A(静态可辨,列为待实证;不先断言已定位)
position callbacks stay monotonic and a legal seek still rewinds(test_player_integration.cpp:1333-1409)的判据结构:
first = callbacks.positionValues()快照 →beforeCount = first.size()、before = first.back()。player.seek(100)→MusicPlayer::Impl::setPosition()经m_workQueue.asyncRunTask异步执行_setPosition(),后者才seekToMs()+bumpPositionSession()+reportPosition(100, resetFloor=true)(合法回退)。waitFor(rewound, 3000)轮询「beforeCount之后存在< before的值」,stepMs=20(Windows 上sleep_for退到约 15.6ms 粒度)。after = callbacks.positionValues();afterMonotonic从beforeCount + 1起逐对检查after[i] < after[i-1]。
第 4 步隐含假设「after[beforeCount] 就是 seek 引起的那个回退值,其后全是新会话」。但 first 快照到 seek 异步任务生效之间,旧会话的消费循环仍在经 asyncRunTask 回投 position(带旧 epoch的任务会在 reportPosition 被丢弃,但已在快照后、seek 生效前已经上报的旧会话值不会被撤回)。只要这段窗口里追加了 ≥1 个旧值,after 就是 ... before, old+Δ, [回退值 100], 新会话...,回退点落在 beforeCount + k (k≥1) 而非 beforeCount,afterMonotonic 便把合法回退误判为「新会话内回退」。
与已知事实吻合:rewound 恒真而只有 afterMonotonic 单独红;失败耗时稳定(是断言失败不是超时);-j4 并发负载拉宽该窗口后命中率上升;与 AGENTS.md NOTES 登记的「断言依赖采样撞上短窗口必假红」「SEEKING 窗口固定 12ms、主循环 5ms 采样在 Windows 退到 15.6ms 粒度」同源。
备选 H_B(必须实证排除):若抓到的失败序列显示真回退发生在「回退值之后」(例如 100 → 更小值),则可能是 reportPosition 的 resetFloor=true 分支(sdk/MusicPlayer.cpp:781-786)在 seek 后被二次触发(换曲路径 putMusicPlayListCurBuf:684-688 也会 bumpPositionSession() + resetFloor),属生产契约问题,须另开新票,本票不越界改生产代码。
决议(AI 推荐,沿用既有一次性批量授权,无需再拍板)
批准一次「改既有判据表达方式」的限定 effort,口径写死如下:
- 修复 = 按实际会话边界切分,不是放宽判据。把「新会话起点」从固定
beforeCount改为在after中定位实际回退点索引rewindAt(第一个< before的位置),只检查rewindAt之后的新会话序列单调性;同时保留「合法回退必须发生」与「新会话内单调不回退」两条契约。 - 不放宽的硬定义:不删任何
CHECK/REQUIRE;不改任何数值容差、waitFor超时(3000ms)、stepMs、seek 目标值、采样门槛;不新增skipCase条件;不改 TIMEOUT / 快集·全量集划分 / 14 个sdk_*目标 / 坏输入 55 例 · 396 断言基线 / CI 配置;不改任何生产代码(sdk/MusicPlayer.cpp、AudioStreamDecoder.*等一律不动);不新增测试专用钩子(避免再引入 C1/C5 与 [实现] stop() 清空未消费 seek 槽并锁定状态契约 #113 的钩子稳定性闸门)。 - 可红可绿是放行前提:人为在新会话内注入一次真回退(变异验证),判据必须红;还原后绿。证明新判据没有把契约判松。
- 实证先行:实现票第一阶段必须抓到失败序列本身(临时诊断输出,取证后零残留),确认是 H_A 还是 H_B;不得跳过实证直接改判据。这是 [决策] 强制重审 seek 竞态:批准第二次限定例外与状态契约加固 #112 踩过的坑(上一轮 100 次单用例压力根本没经过候选窗口,0/100 却被当成证伪证据)。
- 稳定性闸门沿用 [决策] 强制重审 seek 竞态:批准第二次限定例外与状态契约加固 #112 决议 4:分支与 master 同轮数
ctest -j4≥10 轮对照(同机、同 build 目录、同样-j4),分支假红率不得高于基线,且本用例在分支上 0 假红;两轴code-review;Linuxsdk-coverage+ Windowssdk-windows双绿(只认gh run view <id> --json status,conclusion,attempt)。分支假红率高于基线即撤回全部改动并关闭 PR,不合并、不放宽任何判据 / 超时 / 基线。 - 反悔通道:若日后证明新判据只锁实现细节、削弱了契约覆盖,须另开新票同时恢复判据与文档,不得只改判据留下无门禁的状态。
边界(写死,不得扩大)
- 本票不修
42488656322attempt 1 的 SIGSEGV:无复现、无崩溃栈、CI 在 Linux ubuntu-24.04 / 本机取证在 Windows MinGW730,根因仍未定位;H1 已在 Windows 侧证伪、H2 未改、H3/H4 未验。 - 本票不重做 [实现] stop() 清空未消费 seek 槽并锁定状态契约 #113、不重启「强制重审」effort、不合并或 cherry-pick
ca3543fef;本票只是把重做所需的前置条件(干净基线)补齐。后续若要重做仍须另开新票并重走全套闸门。 AGENTS.md的「反复出现」三条门槛不删、不放宽;11-09 破例是一次性留痕,不构成先例。- 不新起 wayfinder 地图;本 effort 用「决策票 + 实现票 + 原生阻塞边」两票结构,与 [决策] 重审「不新造接缝」:批准一个默认关闭的设备错误注入点 #109/[实现] C1 / C5 端到端判据:设备错误 error→state 且不跳轨 #110、[决策] 强制重审 seek 竞态:批准第二次限定例外与状态契约加固 #112/[实现] stop() 清空未消费 seek 槽并锁定状态契约 #113 同构。
验收
- 实证抓到失败序列,确认 H_A / 排除 H_B;诊断代码零残留。
- 新判据在变异注入真回退时精确红、还原后绿。
- 分支与 master 各 ≥10 轮同轮数
ctest -j4对照,分支假红率不高于基线且本用例 0 假红。 - 两轴
code-review通过;PR 阶段 Linux + Windows CI 双绿。 - 文档回填:
AGENTS.mdNOTES(假红根因与「固定索引切会话」反模式)、doc/player-state-contract.md§10.4、当日日志与长期记忆;如实保留「SIGSEGV 根因仍未定位」。
Activity
Merge pull request #117 from wt159/implement/flake-baseline-after-mon…
wt159 commentedon Nov 9, 2026
Resolution:决议 1–6 全部执行完毕,稳定性闸门通过,放行合并
结果:PR #117 以 merge commit
b482b900e合入 master;本票与 #116 由 PR body 的Closes自动 CLOSED。OPEN 票 0 / OPEN PR 0。票正文未改,完整依据留在本 comment 与 PR #117 的两条结论 comment(6738312007进度、6738722031最终判定)。决议逐条落地
sdk/test/unit/test_player_integration.cpp,把「新会话起点」从固定beforeCount+1改为在after中定位实际回退点rewindAt(首个< before),只检查rewindAt+1之后的相邻对。两条契约(合法回退必须发生、新会话内单调不回退)与断言条数(该 suite 111)不变。CHECK/REQUIRE(merger 复核CHECK(40/40、CHECK_MESSAGE(97/97、REQUIRE(9/9);未改 3000ms / stepMs=20 / seek(100) / 采样门槛 / TIMEOUT / 14 个sdk_*目标 / 坏输入 55 例 / CI 配置;未改任何生产代码(git diff全程仅AGENTS.md+ 测试文件);未新增测试专用钩子;未新增skipCase。CHECK(afterMonotonic)精确红(rc=1);字节一致还原 → 单用例 6/6 绿 + 全套 14/14 绿。-j4第 7 轮抓到失败序列beforeCount=24 / before=535 / v[24]=558 / v[25]=100 / v[26]=123:H_A 成立(旧会话在快照后追加 k=1 个值,合法回退落到beforeCount+1,被误判),H_B 排除(无二次回退、回退后 123 递增,无resetFloor二次上报迹象)。诊断git checkout HEAD --还原,merger 复核FLAKE-DIAGgrep=0。-j4、每轮全套 14 目标:分支 10/10 全绿、0 假红(60,59,58,60,59,56,58,59,60,58 s);master915c2bc409/10,第 5 轮sdk_interaction_tests13.73s 失败,日志:1408 CHECK( afterMonotonic )、111 断言 110 通过 1 失败 —— 与 fix: stop() 清空未消费 seek 槽并锁定状态契约(#112 / #113) #114 撤回时两次失败、阶段 1 复现完全同形态。分支 0/10 ≤ 基线 1/10 且本用例 0 假红 → 放行,不触发撤回分支。两轴code-review:Standards 无硬性违规(1 处 Duplicated Code 判断项被仓库约束抑制),Spec 无范围蔓延、代码与票定伪码逐字一致;一条非硬缺陷提示(rewindAt取首个< before依赖 H_A 实证前提,方向为更严假红而非漏判)如实留痕、不改码。PR 阶段 Linux42603640630/ Windows42603640466均completed/successattempt=1,headSha2097825,无 rerun;合并后 push run42607915236/42607915147另行复核。AGENTS.md/ 规格文档,不得只改判据。如实的证据边界
10 轮对 10 轮样本很小,不宣称统计显著;放行依据不是频率差,而是「阶段 1 确定性 H_A 失败序列 + 阶段 2 红/绿变异验证 + 修复版 0 假红且 master 同轮数自然复现同一假红」这一组方向性证据,且严格按事先写死的闸门执行。
边界(不变)
-j4基线假红,为后续同轮数对照提供干净基线。42488656322attempt 1 的 SIGSEGV:无复现、无崩溃栈,CI 在 Linux ubuntu-24.04 / 本机取证在 Windows MinGW730,根因仍未定位;H1 已在 Windows 侧证伪、H2 未改、H3/H4 未验。ca3543fef;后续重做仍须另开新票并重走全套闸门。AGENTS.md的「反复出现」三条门槛不删、不放宽;11-09 破例是一次性留痕,不构成先例。AGENTS.mdNOTES 反模式条、本规格 §10.4、当日日志与长期记忆(合并后的纯文档提交,按 workflowpaths过滤不触发 CI 属预期)。docs: 回填 #115/#116 基线假红 effort 的放行结论与全套证据
wt159 commentedon Nov 9, 2026
补充(不改 resolution):PR #117 合并后的
sdk-coveragepush run42607915236attempt 1 曾failure(sdk_unit_tests :256断言 +sdk_interaction_tests :726同形态 SIGSEGV,是不同 headSha 的第 2 次),rerun --failedattempt 2 全绿。判 flake 四证据齐全,且「反复出现」条件 ① 的「rerun 不能稳定消解」未满足 → 三条门槛仍未命中,维持观测、不另开票、不改生产代码。完整取证与口径见 PR #117 的结论 comment 及AGENTS.md门槛条 /doc/player-state-contract.md§10.4;本票放行结论与边界不变。