@@ -182,6 +182,8 @@ const SLOT: SessionViewSlot = {
182182 onClearToast : ( ) => undefined ,
183183 autoRefineTaskId : 77 ,
184184 onRefineTaskStarted : ( sessionId : number , taskId : number ) => `cb#${ sessionId } /${ taskId } ` ,
185+ /** T17(§C49①):`[[ts:ms]]` 芯片的**页内 seek** 出口(返回标记串 ⇒ 能逐字断言 ms 到位) */
186+ onSeekMs : ( ms : number ) => `seek#${ ms } ` ,
185187} ;
186188
187189/** 每次渲染前清空:`NotePreviewView` 被 mock 成记录器 ⇒ 见证「适配器交给它什么」。 */
@@ -203,7 +205,7 @@ async function previewAdapter(): Promise<(p: SessionViewSlot) => unknown> {
203205}
204206
205207describe ( "A1 `preview` 走会话槽适配器:SessionViewSlot ⇒ NotePreviewView props 逐字映射" , ( ) => {
206- it ( "load 解析出的组件把 detail.session.id / autoRefineTaskId / onRefineTaskStarted 逐字交给 NotePreviewView" , async ( ) => {
208+ it ( "load 解析出的组件把 detail.session.id / autoRefineTaskId / onRefineTaskStarted / onSeekMs 交给 NotePreviewView" , async ( ) => {
207209 const Adapter = await previewAdapter ( ) ;
208210 seen . length = 0 ;
209211 renderToStaticMarkup ( Adapter ( SLOT ) as never ) ;
@@ -216,9 +218,17 @@ describe("A1 `preview` 走会话槽适配器:SessionViewSlot ⇒ NotePreviewVi
216218 expect ( props . autoTaskId ) . toBe ( 77 ) ;
217219 // ③ 回调身份不变(同一引用 ⇒ 下游 onTaskStarted 仍能触发宿主的状态更新)
218220 expect ( props . onTaskStarted ) . toBe ( SLOT . onRefineTaskStarted ) ;
219- // ④ 反面对照:适配器**不得**把整个槽当 props 甩给容器(那正是 `as` 强转的形态)
220- expect ( Object . keys ( props ) . sort ( ) ) . toEqual ( [ "autoTaskId" , "onTaskStarted" , "sessionId" ] ) ;
221+ // ④ 反面对照:适配器**不得**把整个槽当 props 甩给容器(那正是 `as` 强转的形态)。
222+ // ⚠️ T17(§C49①)扩写:期望集合**多出 `onOpenSessionAt`** —— 仍是**逐字等式**(等强:
223+ // 少一个映射键、或多甩一个槽字段都会被这条抓住),只是把新映射的那个出口也钉住。
224+ expect ( Object . keys ( props ) . sort ( ) ) . toEqual ( [ "autoTaskId" , "onOpenSessionAt" , "onTaskStarted" , "sessionId" ] ) ;
221225 expect ( props . detail , "槽本身被当成 props 传下去了(= 强转形态,sessionId 会是 undefined)" ) . toBeUndefined ( ) ;
226+ // ⑤ T17(§C49①):`[[ts:ms]]` 芯片的 **ms 出口** —— 会话页**已经在目标会话里** ⇒ 不是跨页跳转,
227+ // 而是**页内 seek**(`NotePreviewView.onOpenSessionAt(sessionId, ms)` → 槽的 `onSeekMs(ms)`)。
228+ // 没有这条 ⇒「点了没反应的死芯片」可以悄无声息地回来(其变异体 = T17 报告 §4 的 M7)。
229+ const at = props . onOpenSessionAt as ( ( sessionId : number , ms : number ) => void ) | undefined ;
230+ expect ( typeof at , "适配器没把 ms 出口交给 NotePreviewView ⇒ 会话页预览里的芯片是死交互元素" ) . toBe ( "function" ) ;
231+ expect ( at ?.( 1042 , 5000 ) , "芯片的 ms 没走到槽的 `onSeekMs`(页内 seek 断路)" ) . toBe ( "seek#5000" ) ;
222232 } ) ;
223233
224234 it ( "阴性样本:换了槽的 id,映射跟着变(常量冒充当场露馅)" , async ( ) => {
0 commit comments