Skip to content

test: 消除 afterMonotonic 基线假红,重建 -j4 稳定对照基线(#115 / #116) - #117

Merged
wt159 merged 3 commits into
masterfrom
implement/flake-baseline-after-monotonic
Nov 9, 2026
Merged

wt159 merged 3 commits into
masterfrom
implement/flake-baseline-after-monotonic

Conversation

@wt159

@wt159 wt159 commented Nov 9, 2026

Copy link
Copy Markdown
Owner

承接

2026-11-09「强制重审」effort(#112 / #113 / PR #114)按事先写死的稳定性闸门撤回:分支两组 ctest -j4 各 9/10、真实 master 同轮数 10/10 全绿,两次失败完全同形态 —— sdk_interaction_tests / test_player_integration.cpp:1408 的 CHECK(afterMonotonic)。撤回决议写明的重做前置条件是「先解决基线假红放大,或拿到 Linux 侧复现 / ASan 证据」。本 PR 落实前者:只消除这条既有基线假红,重建干净可判定的 -j4 对照基线。

Closes #115
Closes #116

改动(严格最小化)

  • AGENTS.md NOTES:[决策] 消除 afterMonotonic 基线假红,重建 -j4 稳定对照基线 #115 决议落档,新增「异步事件的会话起点按事件内容定位,不要用固定快照下标猜」反模式条。
  • sdk/test/unit/test_player_integration.cpp:把 afterMonotonic 的「新会话起点」从固定 beforeCount+1 改为按序列定位实际回退点 rewindAt(首个 < before),只检查其后的新会话单调。

唯一落地代码文件 1 个,不改任何生产代码、不新增测试钩子、不删任何 CHECK / REQUIRE、不改断言条数、不改任何数值(3000ms / stepMs=20 / seek 100 / 采样门槛 / TIMEOUT / 14 个 sdk_* 目标 / 坏输入 55 例 / CI 配置)。合法回退与新会话内单调两条契约不变,真回退仍会被抓到 → 不是放宽判据。

闸门(按 #115 决议 5、#116 阶段 1–3,逐项回填)

  • 阶段 1 实证:临时诊断只写 stdout、失败时打印 beforeCount / before / 完整 after 序列 / 实际回退点;全套 -j4 跑到复现,判定 H_A / 排除 H_B;诊断零残留。
  • 阶段 2 变异验证:注入新会话内真回退 → 判据精确红;字节一致还原 → 绿;生产文件 git diff 为空。
  • 阶段 3 稳定性闸门:分支与 master 各 ≥10 轮同轮数 ctest -j4,分支假红率不得高于基线且本用例 0 假红。假红率高于基线即撤回全部改动并关闭本 PR,不合并、不放宽任何判据 / 超时 / 基线。
  • 两轴 code-review;PR 阶段 Linux sdk-coverage + Windows sdk-windows 双绿(只认 gh run view <id> --json status,conclusion,attempt)。
  • 文档真源 / 当日日志 / 长期记忆回填,两票 resolution 留完整依据。

边界(写死)

不修 42488656322 的 SIGSEGV(无复现、无栈,CI 在 Linux / 本机取证在 Windows,根因仍未定位);不重做 #113、不合并或 cherry-pick ca3543fef;AGENTS.md 的「反复出现」三条门槛不删、不放宽;不新起 wayfinder 地图。本 effort 只解决基线假红,后续重做须另开新票并重走全套闸门。

wt159 added 3 commits November 9, 2026 18:41
- 按序列内容定位实际回退点 rewindAt(首个 < before 的位置),新会话单调判据从 rewindAt + 1 起算,避开 first 快照到 seek 生效之间旧会话尾部追加 position 造成的固定下标切错。
- 仅调整测试判据,不改任何生产代码。
- 不放宽判据:所有 CHECK/REQUIRE、断言条数、用例/suite 名、数值(3000ms / stepMs=20 / seek 100)保持不变;waitFor(rewound) 仍保证 beforeCount 之后存在 < before 的值,故 rewindAt < after.size() 成立。
- AGENTS.md NOTES 新增「按固定快照下标切会话」反模式条:记录 afterMonotonic 基线假红根因(seek 异步生效 → 旧会话追加 position → 合法回退落到 beforeCount+k)、正确切分方式、以及「实证先行 / 变异验证 / 同轮数 -j4 对照」三道闸门。
- 明确按实际回退点切分不是放宽判据;备选生产 resetFloor 二次上报须另开新票。
- 决议依既有一次性批量授权采用 AI 推荐;票正文不改,结论与逐轮数据留 #116 resolution 回填。
@wt159

wt159 commented Nov 9, 2026

Copy link
Copy Markdown
Owner Author

闸门进度:阶段 1 / 2 已完成,阶段 3 进行中

阶段 1 实证 —— H_A 成立,H_B 排除

诊断版本(临时探针只写 stdout、仅在 afterMonotonic 失败时打印;取证后 git checkout HEAD -- 还原,merger 复核 FLAKE-DIAG grep = 0)全套 ctest --test-dir build/sdk/test -j4 --output-on-failure 第 7 轮复现,sdk_interaction_tests 12.51s 失败、111 断言 110 通过 1 失败,日志 build/flake-diag/round_7.log:

[FLAKE-DIAG] beforeCount=24 before=535 afterSize=27
v[19]=442  v[20]=465  v[21]=488  v[22]=512  v[23]=535 (= before, first.back())
v[24]=558   <- 旧会话在 first 快照之后追加 1 个值 (k=1)
v[25]=100   <- seek(100) 的合法回退,序列中唯一 DESCENT
v[26]=123   <- 新会话,递增

原判据从 beforeCount + 1 = 25 起检查相邻对,于是把 558 → 100 这对跨会话的合法回退误判为「新会话内回退」。这正是 #115 H_A 的形态:seek 经 WorkQueue 异步生效,快照到生效之间旧会话仍追加 position,回退点落在 beforeCount + k。

H_B 排除:序列中只有一次回退,回退点之后 123 单调递增,没有「回退值之后还有更小值」或多次回退,无 resetFloor 二次上报迹象,不需要改生产代码。

补充口径:诊断里 v[19..22] 也标了 LT_BEFORE(早期值自然小于 before=535),但新判据的 rewindAt 搜索从 beforeCount 起,不会误定位到快照范围内的旧值。

阶段 2 变异验证 —— 精确红 → 还原绿

步骤 命令 / 输出
修复版基线 UnitTests.exe -tc="position callbacks stay monotonic and a legal seek still rewinds" → test cases: 1 / 1 passed,assertions: 6 / 6 passed,Status: SUCCESS!,rc=0
注入真回退 临时把 after 改为非 const 并 after.push_back(50)(新会话 123 → 50 真回退)→ :1415 ERROR: CHECK( afterMonotonic ) is NOT correct!,assertions: 6 / 5 passed / 1 failed,Status: FAILURE!,rc=1
字节一致还原 git checkout HEAD -- sdk/test/unit/test_player_integration.cpp,git diff 为空;重编译后单用例 6/6 SUCCESS rc=0;全套 ctest -j4 14/14 全绿 59.38s

生产文件全程未改(sdk/MusicPlayer.cpp 等 git diff 恒为空)。证明按 rewindAt 切分后,新会话内真回退仍会被抓到,检测力未降。

阶段 3 稳定性闸门 —— 进行中

build/flake_gate.sh:分支 10 轮 -j4 → git checkout master 重编译 → master 10 轮 -j4 → 切回集成分支重编译并单用例复核。同机、同 build 目录、同样 -j4。判据按 #115 决议 5 / #116 阶段 3:分支假红率不得高于基线且本用例 0 假红,否则撤回全部改动并关闭本 PR,不合并、不放宽任何判据 / 超时 / 基线。逐轮数据与最终判定将留在本 PR 与两票 resolution。

两轴 code-review

  • Standards:无硬性违规(CRLF 无 BOM、WebKit/4 空格、中文注释、不写共享固定路径、不在判据主循环落额外写、无钩子、断言与数值未动、诊断零残留)。1 处 Duplicated Code 判断项(定位循环与 waitFor lambda 同形),被「就地判据、不新增 helper/钩子、断言条数不变」的仓库约束抑制,不改。
  • Spec:代码与 [实现] 按实际会话边界切分 afterMonotonic 判据,消除 -j4 基线假红 #116 票定伪码逐字一致,无范围蔓延;rewindAt 起点与「找不到回退点」边界安全(rewindAt=size 时二循环不执行,但 CHECK(rewound) 会红,不静默通过);两条契约保留。列出的「文档回填 / 逐轮闸门 / 票 resolution」属流程未完成项,在收口阶段补齐。一条非硬缺陷提示如实留痕:rewindAt 取首个 < before,其正确性系于 H_A 实证前提「快照后旧会话追加值恒 >= before」;若该段出现 < before 的旧值,会提前定位并把合法回退重判成回退 —— 方向是更严的假红而非漏判,且 monotonic CHECK 原本就不覆盖该追加段。不改代码以免偏离票定伪码与「不放宽」口径。

边界不变

本 PR 只解决 -j4 基线假红;不修 42488656322 的 SIGSEGV(无复现、无栈、CI 在 Linux / 本机取证在 Windows,根因仍未定位),不重做 #113、不合并或 cherry-pick ca3543fef;AGENTS.md 的「反复出现」三条门槛不删、不放宽。

@wt159

wt159 commented Nov 9, 2026

Copy link
Copy Markdown
Owner Author

最终判定:稳定性闸门通过,放行合并

阶段 3 同轮数 ctest -j4 对照

同机、同 build 目录、同样 -j4;脚本 build/flake_gate.sh,分支 10 轮 → git checkout master 重编译 10 轮 → 切回集成分支重编译。每轮都是全套 14 个 sdk_* 目标,不是单目标串行。

组 结果 逐轮耗时 (s)
集成分支 209782555(修复版) 10/10 全绿、0 次 afterMonotonic 假红 60, 59, 58, 60, 59, 56, 58, 59, 60, 58
master 915c2bc40(旧判据) 9/10,第 5 轮 sdk_interaction_tests 失败 13.73s 58, 59, 58, 57, 58, 55, 58, 57, 57, 59

master 第 5 轮日志 build/flake-gate/master_round_5.log:test_player_integration.cpp:1408 ERROR: CHECK( afterMonotonic ) is NOT correct!、test cases: 19 / 18 passed / 1 failed、assertions: 111 / 110 passed / 1 failed —— 与 PR #114 撤回时两次失败、以及本 effort 阶段 1 的诊断复现(round 7,12.51s)完全同形态。切回集成分支重编译后单用例复核 6/6 SUCCESS、工作区无源码改动。

判定:分支假红率 0/10 ≤ 基线 1/10,且本用例在分支上 0 假红 → 满足 #115 决议 5 / #116 阶段 3 的放行条件;不触发「撤回并关闭 PR」分支。

如实说明:10 轮对 10 轮样本很小,不宣称统计显著。本次证据强度来自「修复版 0 假红 + master 同轮数自然复现 1 次同一假红」这一方向性对照,叠加阶段 1 抓到的确定性 H_A 失败序列与阶段 2 的红/绿变异验证,而不是单靠频率差异。

PR 阶段双平台 CI

只认 gh run view <id> --json status,conclusion,attempt:

run 工作流 headSha 结论
42603640630 sdk-coverage(Linux ubuntu-24.04) 2097825 completed/success attempt=1
42603640466 sdk-windows 2097825 completed/success attempt=1

无 rerun、无放宽超时、无跳过目标。

闸门汇总(#115 决议 / #116 验收逐条)

  • 阶段 1 实证:诊断版全套 -j4 第 7 轮抓到 beforeCount=24 / before=535 / v[24]=558 / v[25]=100 / v[26]=123 → H_A 成立、H_B 排除;诊断零残留。
  • 阶段 2 变异验证:注入新会话内真回退 → CHECK(afterMonotonic) 精确红(rc=1);git checkout HEAD -- 还原后 diff 为空,单用例 6/6 绿、全套 -j4 14/14 绿 59.38s;生产文件恒未改。
  • 阶段 3 闸门:见上表,通过。
  • 两轴 code-review:Standards 无硬性违规(1 处 Duplicated Code 判断项被仓库约束抑制);Spec 无范围蔓延、代码与票定伪码逐字一致,其余为流程未完成项与一条非硬缺陷提示(已在前一条 comment 如实留痕,方向为更严的假红而非漏判,不改码以免偏离票定伪码)。
  • 文档真源回填(doc/player-state-contract.md §10.4、AGENTS.md 补「本 effort 只解决基线假红 / SIGSEGV 根因仍未定位」、当日日志与长期记忆)与两票 resolution 在合并后落档,票正文不改。

边界(不变)

本 effort 只解决 -j4 基线假红,让后续同轮数对照有干净基线。不修 42488656322 的 SIGSEGV —— 无复现、无崩溃栈,CI 崩在 Linux ubuntu-24.04 而本机取证在 Windows MinGW730,根因仍未定位,H1 已在 Windows 侧证伪、H2 未改、H3/H4 未验。不重做 #113、不合并或 cherry-pick ca3543fef;AGENTS.md 的「反复出现」三条门槛不删、不放宽。后续重做仍须另开新票并重走全套闸门。

@wt159
wt159 marked this pull request as ready for review November 9, 2026 11:17
@wt159
wt159 merged commit b482b90 into master Nov 9, 2026
2 checks passed
wt159 added a commit that referenced this pull request Nov 9, 2026
- AGENTS.md 反模式条补「本 effort 只解决基线假红 / SIGSEGV 根因仍未定位」、PR #117 收口与同轮数对照数据。
- doc/player-state-contract.md §10.4 新增放行记录:阶段 1 实证失败序列(H_A 成立 / H_B 排除)、阶段 2 红绿变异验证、阶段 3 分支 10/10 vs master 9/10 闸门、两轴 code-review 与双平台 CI、边界与反悔通道。
- 当日日志追加第十八轮(implement-spec 流程骨架、worktree/tdd/merger、全流程取证与坑);MEMORY.md 更正终态 OPEN 票/PR 归零并固化修复事实。
- 两票 resolution 已留 GitHub;纯文档提交按 workflow paths 过滤不触发 CI 属预期。
@wt159
wt159 deleted the implement/flake-baseline-after-monotonic branch November 9, 2026 11:24
@wt159

wt159 commented Nov 9, 2026

Copy link
Copy Markdown
Owner Author

合并后 push run 的 flake 取证(如实补充,不改写放行结论)

PR 阶段双绿(42603640630 Linux / 42603640466 Windows,headSha 2097825,均 success attempt=1)与本地闸门结论不变;但合并后 push run 曾有一次 failure,必须单独交代:

run 结果
42607915147 sdk-windows push b482b90 completed/success attempt=1
42607915236 sdk-coverage push b482b90 attempt 1 completed/failure → gh run rerun --failed → attempt 2 completed/success

attempt 1 失败形态(coverage job / 步骤 6 Build coverage target)

86% tests passed, 2 tests failed out of 14,80.98s:

  1. 8/14 sdk_unit_tests ***Failed 19.90 sec:test_player_integration.cpp:256 / MusicPlayer Error Handling / play without track triggers error callback → ERROR: CHECK( listener.error_count > 0 ) is NOT correct!(417 例 416 通过 / 49468 断言 49467 通过)。
  2. 14/14 sdk_interaction_tests ***Failed 6.26 sec:test_player_integration.cpp:726 / MusicPlayer Interactive Paths / seek to middle moves position forward → FATAL ERROR: test case CRASHED: SIGSEGV(14 断言全过、0 断言失败、Segmentation fault)—— 与历史 push run 42488656322 attempt 1 完全同形态,且是不同 headSha(8b36430 → b482b90)上的第 2 次。

判 flake 四证据(按 AGENTS.md NOTES)

  • ① 同一代码 PR run 已绿:42603640630 success attempt=1;git diff --stat 209782555 b482b900e 为空 → PR head 与 merge commit tree 逐字节相同;d8cb75b96 相对 merge commit 仅 AGENTS.md + doc/player-state-contract.md 纯文档。
  • ② 「失败目标不在改动文件」不成立(两个失败都在 test_player_integration.cpp,本 effort 唯一落地文件),故按登记的替代取证:doctest suite 过滤器(sdk/test/CMakeLists.txt:193,196,234)确认失败用例分属 MusicPlayer Error Handling / MusicPlayer Interactive Paths,与本次改动的 PublicPlayer Interactive Paths / position callbacks stay monotonic and a legal seek still rewinds 零交集;改动仅新增局部变量 rewindAt 与只读循环,无全局状态、无生产代码改动。
  • ③ 常态耗时吻合:同 workflow 成功 run 42603640630 为 sdk_unit_tests 16.01s / sdk_interaction_tests 12.26s / 100% tests passed;失败 run 的 6.26s 是 SIGSEGV 早退,不是等待超时。
  • ④ gh run rerun 42607915236 --failed → attempt 2 completed/success,与首次 SIGSEGV 的处理一致,只做一次 rerun 取证,未放宽任何超时 / TIMEOUT / 坏输入 55 例基线 / CI 配置。

(run 已是 attempt 2 时 gh run view --log-failed 看不到 attempt 1,attempt 1 的 job/steps 用 gh api repos/wt159/SoundBridge/actions/runs/42607915236/attempts/1/jobs 补查。)

门槛状态:仍未命中,维持观测

AGENTS.md 的「反复出现」条件 ① 要求「不同 headSha 上同形态 SIGSEGV ≥2 次且 rerun --failed 不能稳定消解」。本次虽是第 2 次同形态,但两次都被 rerun 稳定消解(42488656322 a2 / 42607915236 a2 均 success),故 ① 未满足;② 本机 Windows -j4 0/10、单用例 0/100;③ 仍无崩溃栈 / ASan 报告。三条门槛仍未命中 → 不另开票、不改生产代码、不改生产包装层,别把「第 2 次出现」直接读成门槛命中。

结论

本 effort 的交付与放行判定不变(阶段 1 确定性实证 + 阶段 2 红绿变异 + 阶段 3 分支 10/10 vs master 9/10 + 两轴 review + PR 阶段双平台 CI 双绿 + 合并后 rerun 全绿)。如实保留合并后 push run attempt 1 的 failure 记录,不粉饰为「全程双绿」。SIGSEGV 根因仍未定位(CI 在 Linux ubuntu-24.04 的 coverage 构建,本机取证在 Windows MinGW730,不可外推);本 effort 只解决 -j4 基线假红,重做 #113 仍须另开新票并重走全套闸门。

wt159 added a commit that referenced this pull request Nov 9, 2026
- AGENTS.md 门槛条补第 2 次同形态 SIGSEGV(b482b90 / 42607915236 a1)与 sdk_unit_tests :256 新形态断言 flake;明确两次都被 rerun 稳定消解 → 三条门槛仍未命中,维持观测、不另开票、不改生产代码;补同文件失败时的替代取证要点与 attempts/1/jobs 取证坑。
- doc/player-state-contract.md §10.4 补合并后 CI failure / rerun a2 success / 判 flake 四证据 / 门槛状态,如实保留「合并后曾有 failure」,不粉饰为全程双绿。
- 当日日志与长期记忆同步;PR #117 与两票追加结论 comment。
- 纯文档提交按 workflow paths 过滤不触发 CI 属预期。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant