Skip to content

[决策] 重审「不新造接缝」:批准一个默认关闭的设备错误注入点 #109

Closed

Description

@wt159

背景

doc/player-state-contract.md §10.4:213 / §10.3:198 登记的唯一残留技术缺口:C1 的 error→state 顺序、C5 的「设备错误不跳轨」缺端到端判据。原因是现有接缝无法稳定注入「带状态变化的错误」,而 §8:150-151 写「判据不新造 / 不做最小可测替身」;doc/observability-contract.md §1:16、§1:20、§7.4:207 也把「新增可注入错误接缝」列为界外 / 不可推翻前提。

2026-11-08 用户拍板「启动补齐 effort」,本票先重审这些条款(一票一决策),实现走后续票。

只读调研结论(为什么必须新开接缝)

  • 现有三条错误路径都产不出目标序列:空列表 play() 走 cur==nullptr(test_player_integration.cpp:229,甚至断言无状态变化);截断素材只断言 error_count>=1(:892);test_error.cpp:147 只是静态查 GetErrorInfo().action 表。
  • MusicPlayListCallback 被 MusicPlayer::Impl 私有持有,测试拿不到;AudioDevice 全非虚、AudioDevice::start() 恒 return 0(AudioDevice.cpp:318),StartFailed 分支不可达;唯一能造成设备失败的是 SDL_AUDIODRIVER 进程级覆写,会污染同进程全部用例且平台相关。
  • 不改生产代码,写不出稳定可红可绿的端到端判据;硬凑(坏素材 + setAutoSkipOnError(false))验证的是实现细节而非契约,且 :890 有 wav demuxer 跨平台假红前科。

裁决(拍板选最保守推荐):批准注入,但严格限定形态

  1. 只在 AudioDevice::open() 的包装层(sdk/audio/device/AudioDevice.cpp:302)加一个默认关闭的失败开关:open() 命中开关时直接 return -1,不进 Impl::open()、不碰 SDL。这样播放链走的是生产里真实存在的设备失败分支(MusicPlayer.cpp:326-330 → onMusicPlayListError:707),sdk/MusicPlayer.cpp 播放逻辑零改动。
  2. 开关用文件级 std::atomic<bool>(默认 false),经 AudioDevice 的一个 static 测试专用方法设置;只在控制线程的 _play() → open() 路径上被读一次,绝不落在解码线程 / 10 ms 消费主循环 / 判据主循环(O1 教训:额外写把本机 -j4 假红从 0 抬到约 30%)。
  3. 不碰公开 API:sdk::MusicPlayer 是遗留内部接口,本次连它都不改;soundbridge::Player(sdk/include/soundbridge/player.h)及其七个 void 控制入口、三态、回调契约一字不动。
  4. 一条 AudioDeviceOpenFailed(ErrorAction::StopPlayback)序列同时覆盖 C1(onError 早于 onStateChanged(Stopped)、发且仅发一次)与 C5(默认 autoSkipOnError()==true 时也不跳轨、当前索引不变)。

硬约束(不可推翻)

  • 不改任何既有判据数值 / 容差、不新增 add_test 分组、不改 14 个 sdk_* 目标 / 7 组 TIMEOUT / CI 配置 / BadInput 55 例 396 断言 / 覆盖度 15 行矩阵;新用例写文件沿用带 pid 的 TempMediaDir。
  • 不新增同步解码入口、不改 positionMs 归属、不改 10 ms push 节奏;StreamMetrics 七字段与 O5 归档的每 run 24 行 MESSAGE 基线零变化。
  • 后续 effort:L1/L2 观测指标与 drift 的数值阈值拍板 #104「不设任何数值阈值」与 §3.2 第 5 步永久生效不变;本票不拍任何数字、不新增非门禁观测面。
  • 新用例必须是稳定可红可绿的契约判据,不得靠裸 sleep / 绝对时长窗口 / 特定素材的 demuxer 行为;沿用 waitFor 与队列屏障惯例。

稳定性闸门(沿用 O1 先例)

  • 本地 ctest -j4(cwd sdk/test、三重 PATH):master 基线 ≥10 轮与集成分支 ≥10 轮对照,目标 14/14 全绿。
  • 若分支假红率高于基线,撤回全部 sdk/ 改动、裁为不落地,把对照表与结论写进规格和本票 resolution,不改判据 / 不放宽时序窗口来消化。
  • 跨平台改动须等 Linux sdk-coverage 与 Windows sdk-windows 双绿(AGENTS.md / 规格 §8.4)。

反悔与边界

依据:doc/player-state-contract.md §8 / §10.3 / §10.4,doc/observability-contract.md §1 / §4.4 / §7.4 / §8.4,#105 的 ctest -j4 对照实验,AGENTS.md 跨平台约定。

Activity

  1. wt159 commented on Nov 8, 2026

    @wt159
    OwnerAuthor

    决议(2026-11-08,用户拍板「启动补齐 effort」并按一次性批量授权选最保守推荐):批准新增一个默认关闭的设备错误注入点,重审「不新造接缝」条款,但严格限定形态。

    依据:只读调研确认三条既有路径(空列表 play / 截断素材 / 静态 action 查表)都产不出「带状态变化的设备错误」序列;MusicPlayListCallback 被 Impl 私有持有、AudioDevice::start() 恒返回 0、SDL_AUDIODRIVER 是进程级且平台相关 —— 不改生产代码无法写出稳定可红可绿的端到端判据,硬凑只能验证实现细节。

    批准范围:① 只在 AudioDevice::open() 包装层加默认 false 的文件级 std::atomic<bool>,命中直接 return -1,不进 Impl::open() / 不碰 SDL,sdk/MusicPlayer.cpp 播放逻辑零改动;② 只在控制线程 _play()→open() 路径读一次,绝不落解码线程 / 消费主循环 / 判据主循环(O1 -j4 假红教训);③ 不碰 soundbridge::Player 公开头与七个 void 控制入口;④ 一条 AudioDeviceOpenFailed 序列同时覆盖 C1 顺序与 C5 不跳轨。

    闸门:master 基线 ≥10 轮 vs 集成分支 ≥10 轮 ctest -j4 全绿;分支假红率高于基线即撤回全部 sdk/ 改动、裁不落地,不改判据 / 不放宽时序窗口消化。跨平台须等 Linux sdk-coverage 与 Windows sdk-windows 双绿。

    边界:只重审这一条,不重开 E/C/O 链、不重开 #104 / #105、不碰规格界外的网络流 / URL 数据源。#104「不设数值阈值」与 §3.2 第 5 步永久生效不变。原生阻塞边 #110 → #109 已建立,实现与验证走 #110。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    ready-for-human需要人来做决定或动手

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions