## Parent [#85](https://github.com/wt159/SoundBridge/issues/85) — [Spec] 播放器状态与公开 API 契约实现计划。 ## What to build 把「`duration() == 0` 时 seek 是空操作」从实现巧合升级为**可红可绿的判据**:位置不回退、不发新回调、不改状态、不发 `onError`;`pos == 0` 例外保留(归零),`pos > durationMs` 的静默丢弃与之一致。调用方以 `duration() == 0` 一个信号判断不可 seek,不引入能力位。 - 生产链行为若已符合则**不改代码**,只补用例;`INVALID_OPERATION` 保持内部降级码、不对外暴露。 - 用既有交互测试分组,断言四条「无变化」与 `pos == 0` 例外。 ## Acceptance criteria - [ ] 标称时长为 0 且目标 >0 时,四条「无变化」判据成立 - [ ] `pos == 0` 例外与超界静默丢弃按规格处理 - [ ] 不新增任何公开 API、错误码或 `onError` 上报 ## Blocked by [#86](https://github.com/wt159/SoundBridge/issues/86)(GitHub 原生 blocked_by 已连接)。. **必须遵守(来自 spec、ADR 0002/0003/0004 与 `doc/bad-input-spec.md`):** - 七个控制入口保持 `void`;不新增错误码、不改 `onError` 签名、不新增状态机、不扩状态集合(对外仍 `Playing/Paused/Stopped` 三态)。 - 判据**不新造数值**:沿用 `max(1%,150ms)`、`r × good`、5pp、零容差差分、getter 与回调 ≤50ms、状态序列无相邻重复、每曲一次 duration。 - 坏输入 55 例 / 396 断言与覆盖度矩阵 15 行**一字不动**;14 个 `sdk_*` ctest 目标、TIMEOUT、`-j4`、快集 / 全量集划分全部不动。 - 新增用例若写文件必须带 pid(`-j4` 撞名假红的教训);线程契约用 `promise/future` 或轮询验证,不裸 sleep。 - 事实基线见 [#76](https://github.com/wt159/SoundBridge/issues/76) 的 `research/public-api-contract-facts` 分支;术语见 `GLOSSARY.md`。
Activity
test: 标称时长为 0 / 超界时 seek 的空操作判据(#89 / T04)
wt159 commentedon Nov 8, 2026
Resolution(2026-11-08,图外实现 effort #85 / PR #93)
生产链行为本已符合规格 §7,本票不改代码,只把「四条无变化」升级为可红可绿判据。经 code-review 修正后,两条用例都真正进入目标路径:
duration()==0:seek(5000)后用一次必然上报的play()作队列屏障,断言没有 position / state 回调、错误只来自屏障、位置保持 0、状态 Stopped。play()让currentTask存在,才真正走到_setPosition的pos > durationMs降级 return(与durationMs==0 && pos>0同源);用「又来一个 position 回调」作队列推进信号,断言位置没跳到目标、错误与状态不变。pos==0例外不产生错误或状态变化。去掉裸 sleep,无声卡场景沿用既有
skipCase。不新增公开 API / 错误码 /onError上报。