## 背景
用户反馈:用 LLM 开发时 VOBS_C210(effect 自订阅)**非常频繁**,且错误信息里的信号名
永远是 (未命名信号) —— 不知道该改哪一行。
## 本次做的(原计划的第 2 条)
C210 / C211 的 fix 此前只给 `untrack`。那是**局部补丁**:它让这次写入不再触发重跑,
但没回答"这个 effect 为什么订阅了它"。所以同类问题反复复发。
现在按「先教结构、再教补丁」重排:
1. **首选** `effect(on(deps, () => { … }))` —— 显式声明依赖,回调在 untrack 作用域里跑,
它调用的函数碰什么信号都不会反向订阅(**结构上写不出来**,1.8.3 加入,对齐 SolidJS)
2. **次选** 改用 `memo` / 派生值 —— 最常见的形态"读 A 写 A"其实想问"派生出新值"
3. **兜底** 才是 `untrack(() => { X.value = next })`
C210 的 example 改为示范 `on()`;C211 补一句"被调函数在首个 await 之前的代码也是同步
执行的 —— effect 里只调了个函数不等于没依赖"(对应 1.8.3 的 VOBS_C106)。
既有 dev.test.ts 断言 example 含 'untrack',随这次刻意的方向调整改为断言含 'on(',
并额外断言 fix 文本**同时**仍有 untrack(作为兜底),避免以后有人把兜底删掉。
## 原计划的第 1 条:核验后**撤销**,因为它已经存在
我原打算"让编译器给 state 声明注入变量名"。实现到一半,既有测试把我拦住了:
× 保留非 JSX 声明的初始化参数
× **state 被本地声明遮蔽时不推断 debugName**
查证后发现:**这个功能早就完整实现**——
- `compile.ts:1046` `inferStateDebugName()`:从变量名推断 debugName
- `compile.ts:39` 记录从 @vobs/reactivity / @vobs/vobs 导入的 state 别名(含 as 别名)
- `compile.ts:41` **本地同名声明遮蔽时禁用推断**(防止给非框架信号起假名字)
- `signal.ts:158` `state<T>(initialValue, debugName?)`
- `dev.ts` `signalLabel()` 正确读 `getSignalDebugName`
**我的实现是重复造轮子,而且更差** —— 它不看符号来源,probe 里 `state` 根本没 import
也照样注入。**假名字比没名字更难查**,所以整个撤销。
机制已全部回退(git checkout 三个文件),只留本次的 fix 文案改动。
**所以 (未命名信号) 的成因不是"缺功能"**,而是编译器的推断在那种形态下没跑到。
两个待核实的候选(需要用户信息才能定):
1. 该信号所在的 **.ts store 文件没被 vite 插件编译** —— 插件对 .ts 有闸门
(`isStateModulePath` / `isStatefulModule` / hmrStateEnabled),跳过就不注入
2. `state` 从**用户的 barrel / 再导出**引入,编译器认不出它来自 @vobs/reactivity / @vobs/vobs
全量门禁 1384 测试全绿 · typecheck 0 · check:source 0。