JianFeeeee
d65b742bd7
fix(plugin): 修两处持锁自死锁(CI 双红真因)+ tools_ready 事件声明
## 死锁(这是 CI 连续两次红的真因)
`StopAll` 与 `StopPlugin` 都在持有 `r.mu` **写锁**时调用
`RemoveBuiltinSkill` → `skillDirOf` → `r.mu.RLock()` ⇒ **自死锁**。
后果不是报错而是**卡死**:
- internal/plugins 卡 300s 超时(TestCapability_RestrictedPluginStillLoads)
- internal/plugin 卡 840s 超时(TestStopPluginDoesNotTouchPersistentState)
- CI 的 `go test ./...` 与 `go test -race` 双双红
修法:拆出**不加锁**的内部版本,持锁路径只走它:
- `skillDirFrom(dataDir, name)`(纯函数)
- `removeBuiltinSkillLocked(pluginName, p, dataDir)`(显式传 dataDir,
避免"看起来没取锁、一改就取锁"的隐患)
- `announceSkillRemovedLocked`(持锁下直读 r.evBus)
修后:internal/plugins 300s → 12s,internal/plugin 840s → 0.7s。
## 防回归判据
`TestStopAllAndStopPluginDoNotDeadlock`:死锁**不返回**,普通断言抓不到,
所以用**超时**当判据(5 秒未返回即失败),并指明应改用 Locked 版本。
## tools_ready 事件声明
新增的 tools_ready 触发 `TestEveryPublishedEventHasAnOutwardPath`
(该判据防"事件发了、客户端收不到"的静默失效)。
tools_ready 是**内核内部**就绪信号(plugin-host → seq 等订阅者),
不是对话流程事件,前端无需感知 ⇒ 在 allowed 里显式声明理由。
## 验证
go build ./... / go vet ./... / go test -p 1 ./... / -race 全通过。
2026-10-25 18:25:37 +08:00
..
2026-10-25 18:25:37 +08:00
2026-10-22 19:49:25 +08:00
2026-09-11 20:31:50 +08:00
2026-10-21 12:17:19 +08:00
2026-10-21 12:17:19 +08:00
2026-10-21 12:17:19 +08:00
2026-10-21 12:17:19 +08:00
2026-10-22 20:49:44 +08:00
2026-10-05 11:25:20 +08:00
2026-10-08 10:41:07 +08:00
2026-10-08 10:41:07 +08:00
2026-10-05 11:25:20 +08:00
2026-10-05 11:25:20 +08:00
2026-10-05 11:25:20 +08:00
2026-10-05 11:25:20 +08:00
2026-09-11 11:45:24 +08:00
2026-10-12 17:18:04 +08:00
2026-10-25 15:55:26 +08:00
2026-10-17 19:18:24 +08:00
2026-10-08 12:35:28 +08:00
2026-10-05 11:25:20 +08:00
2026-10-25 15:55:26 +08:00
2026-10-05 11:25:20 +08:00
2026-10-05 11:25:20 +08:00
2026-09-11 11:45:24 +08:00
2026-07-25 11:17:31 +08:00
2026-10-21 12:17:19 +08:00
2026-10-05 11:25:20 +08:00
2026-07-29 14:48:23 +08:00
2026-10-25 15:55:26 +08:00
2026-10-05 11:25:20 +08:00
2026-10-12 16:23:23 +08:00
2026-10-21 12:17:19 +08:00
2026-10-05 11:25:20 +08:00
2026-10-25 15:55:26 +08:00
2026-10-05 11:25:20 +08:00
2026-10-05 11:25:20 +08:00
2026-10-22 20:49:44 +08:00
2026-10-05 11:25:20 +08:00
2026-09-13 09:32:29 +08:00
2026-10-12 14:26:13 +08:00
2026-10-25 18:25:37 +08:00
2026-10-05 11:25:20 +08:00
2026-10-25 15:55:26 +08:00
2026-10-05 11:25:20 +08:00
2026-10-08 16:41:03 +08:00
2026-09-11 20:31:50 +08:00
2026-09-11 20:31:50 +08:00
2026-10-22 20:49:44 +08:00
2026-09-13 09:38:54 +08:00
2026-10-05 11:25:20 +08:00
2026-10-05 11:25:20 +08:00
2026-10-17 19:18:24 +08:00
2026-10-12 16:55:40 +08:00
2026-10-22 20:49:44 +08:00
2026-10-25 15:55:26 +08:00
2026-10-05 11:25:20 +08:00
2026-10-12 10:13:36 +08:00
2026-10-05 11:25:20 +08:00
2026-10-12 14:26:13 +08:00
2026-10-05 11:25:20 +08:00
2026-10-21 12:17:19 +08:00
2026-10-05 11:25:20 +08:00
2026-10-17 19:18:24 +08:00
2026-10-05 11:25:20 +08:00
2026-08-05 09:59:30 +08:00
2026-10-05 11:25:20 +08:00
2026-10-05 11:25:20 +08:00
2026-10-05 11:25:20 +08:00
2026-10-05 11:25:20 +08:00
2026-10-05 11:25:20 +08:00
2026-09-13 09:38:54 +08:00
2026-09-26 20:16:11 +08:00
2026-09-15 10:20:40 +08:00
2026-09-26 20:16:11 +08:00
2026-09-26 20:16:11 +08:00
2026-10-05 11:25:20 +08:00
2026-10-08 10:41:07 +08:00
2026-10-25 15:55:26 +08:00
2026-10-12 10:13:36 +08:00
2026-10-12 10:13:36 +08:00
2026-10-17 19:18:24 +08:00
2026-09-13 14:09:35 +08:00
2026-10-21 12:17:19 +08:00
2026-10-21 12:17:19 +08:00
2026-10-17 19:18:24 +08:00
2026-08-14 00:48:40 +08:00
2026-10-05 11:25:20 +08:00