@@ -73,21 +73,23 @@ const T1_SECTION_B_37: readonly string[] = [
7373
7474/** 登记例外:**点名 + 理由**(缺口必须可见;不许从账本消失) */
7575const EXCLUDED : Readonly < Record < string , string > > = {
76- "components/AiProviderSettings.tsx" : "与 T11 并行撞车(同一文件同时被两个任务点名)" ,
77- "components/GroupRowContextMenu.tsx" : "T8 的 dialogMigration.e.test.ts:240-244 禁止 NON_MIGRATED_14 import 原语(B1)" ,
78- "components/RichEditorView.tsx" : "同上(B1 锚定菜单)" ,
76+ "components/GroupRowContextMenu.tsx" : "B1:T8 的 dialogMigration.e.test.ts:240-244 禁止 NON_MIGRATED_14 import 原语" ,
77+ "components/RichEditorView.tsx" : "B1:同上(锚定菜单)" ,
7978} ;
8079const MIGRATED = T1_SECTION_B_37 . filter ( ( f ) => EXCLUDED [ f ] === undefined ) ;
8180
8281/** 缺口:这些文件**还剩几处** `style={xxxBtn}`(实测值;补做时这里先红) */
8382const GAP_SITES : Readonly < Record < string , number > > = {
84- "components/AiProviderSettings.tsx" : 8 ,
8583 "components/GroupRowContextMenu.tsx" : 2 ,
8684 "components/RichEditorView.tsx" : 3 ,
8785} ;
8886
87+ /** 已补齐的历史缺口(T11 落库后由 T12 补做)—— 留档,防止"缺口从账本消失" */
88+ const FILLED_GAP = { file : "components/AiProviderSettings.tsx" , sites : 8 , why : "曾与 T11 并行撞车;T11 落库后补做" } as const ;
89+
8990/** 仍被引用的 `const *Btn*` 白名单(`文件|常量名`)—— **只有 spread 消费者**的常量按兵不动 */
9091const STILL_REFERENCED : readonly string [ ] = [
92+ "components/AiProviderSettings.tsx|btn" ,
9193 "components/AiRefineCard.tsx|btn" ,
9294 "components/AiServicePanel.tsx|btn" ,
9395 "components/AiTaskPanel.tsx|btn" ,
@@ -126,6 +128,7 @@ const STILL_REFERENCED: readonly string[] = [
126128
127129/** 换出来的 `Button` 形状表:`文件 → (variant,size) 形状 → 计数`(迁移后实测) */
128130const BUTTON_SHAPES : Readonly < Record < string , Readonly < Record < string , number > > > > = {
131+ "components/AiProviderSettings.tsx" : { "variant=secondary size=md" : 8 } ,
129132 "components/AiRefineCard.tsx" : { "variant=secondary size=md" : 1 } ,
130133 "components/AiServicePanel.tsx" : { "variant=secondary size=md" : 1 } ,
131134 "components/AiTaskPanel.tsx" : { "variant=secondary size=sm" : 3 } ,
@@ -162,7 +165,7 @@ const BUTTON_SHAPES: Readonly<Record<string, Readonly<Record<string, number>>>>
162165 "pages/GoalsPage.tsx" : { "variant=primary size=md" : 1 , "variant=secondary size=md" : 1 } ,
163166} ;
164167/** 形状表覆盖的 `Button` 总数(= 迁移处数;棘轮的 Δ 必须与它逐字相等) */
165- const MIGRATED_SITES = 91 ;
168+ const MIGRATED_SITES = 99 ;
166169/** 迁移前读数(`dev@bde807dc` 导出树,同一仪器实测):棘轮基线**只许在这条线以下** */
167170const PRE_T12_NATIVE_BUTTONS = 493 ;
168171
@@ -199,11 +202,13 @@ describe("T12 · 仪器自证(正/负对照 · 剥注释 · 空真排查)",
199202 expect ( MIGRATED . length + Object . keys ( EXCLUDED ) . length ) . toBe ( 37 ) ;
200203 for ( const rel of T1_SECTION_B_37 ) expect ( read ( rel ) . length , `读不到 ${ rel } ` ) . toBeGreaterThan ( 0 ) ;
201204 expect ( Object . keys ( GAP_SITES ) . sort ( ) , "缺口表与例外表不是同一组文件" ) . toEqual ( Object . keys ( EXCLUDED ) . sort ( ) ) ;
202- expect ( MIGRATED . length , "已迁文件数不像话(清单读错会在这里显形)" ) . toBe ( 34 ) ;
205+ expect ( MIGRATED . length , "已迁文件数不像话(清单读错会在这里显形)" ) . toBe ( 35 ) ;
206+ expect ( MIGRATED , "曾登记的历史缺口已补齐(它必须回到已迁清单里)" ) . toContain ( FILLED_GAP . file ) ;
207+ expect ( directHits ( read ( FILLED_GAP . file ) ) , `补做过的 ${ FILLED_GAP . file } 又冒出直接形态命中` ) . toBe ( 0 ) ;
203208 } ) ;
204209} ) ;
205210
206- describe ( "① 直接形态 style={xxxBtn} 在 34 个已迁文件里归零" , ( ) => {
211+ describe ( "① 直接形态 style={xxxBtn} 在 35 个已迁文件里归零" , ( ) => {
207212 it ( "逐文件 directHits === 0;缺口文件的实测处数 == 登记值(仪器在缺口上有非零读数 ⇒ 不是看不见)" , ( ) => {
208213 const bad = MIGRATED . filter ( ( rel ) => directHits ( read ( rel ) ) !== 0 )
209214 . map ( ( rel ) => `${ rel } : ${ directHits ( read ( rel ) ) } ` ) ;
@@ -234,7 +239,7 @@ describe("② 常量族台账:孤立常量 = 0,仍被引用者 == 白名单"
234239} ) ;
235240
236241describe ( "③ Button 形状表:换出来的原语必须与冻结的 (variant,size) 逐文件一致" , ( ) => {
237- it ( "逐文件形状计数相等,且总数 == 91 (把 primary 写成 secondary 这里必红)" , ( ) => {
242+ it ( "逐文件形状计数相等,且总数 == 99 (把 primary 写成 secondary 这里必红)" , ( ) => {
238243 const diffs : string [ ] = [ ] ;
239244 let total = 0 ;
240245 for ( const rel of MIGRATED ) {
0 commit comments