revert: 撤掉多余的 auto_start 门(调度器早已处理)

## 为什么要撤

c426921 我以为"外部插件的 auto_start 完全不生效"。**判断错了。**

实机验证:13 个声明 auto_start=false 的插件在重启后确实没加载
(建链 22 → 11)。靠的是**既有机制**,不是我加的门:

	internal/kernelboot/scheduler.go:277  canLaunch: if !p.AutoStart { return false }
	internal/kernelmod/pluginhost/mod.go  buildSkipSet: catalog 里的插件全交给调度器
	internal/kernelmod/pluginhost/catalog_test.go:198  判据已覆盖

我当时只看到 `Load` 遍历目录时不查 auto_start,就断定该字段不生效 ——
那只是**没看到另一条路径**(LoadSkipping + 调度器分层)。

## 为什么必须撤而不是留作"兜底"

· 两处逻辑重叠:调度器按 catalog 决定跳过,我的门在 loadOne 里再判一次。
  两处各说各话,将来改一处漏另一处就是新的静默不一致。
· 我那条判据测的是**我自己加的门**,不是真实行为 —— 它变绿不证明任何
  产品行为正确(撤掉这道门,判据红,但产品行为不变)。
· **没验证过的防御就是噪音。**

## 撤回后行为不变

按需加载链路实测(weather):
	plugin_start → loaded=true / alive=true / pid=838963
	plugin_stop  → loaded=false / alive=false,pid 消失
	两者都 persistent="未改动"(不动持久禁用清单)

这些都发生在**没有**我这个门的旧二进制上。
This commit is contained in:
JianFeeeee
2026-10-18 13:36:16 +08:00
parent 59f7001932
commit 6a15b80ee9
2 changed files with 1 additions and 201 deletions

View File

@ -574,21 +574,6 @@ func pluginEntryHash(plgDir string) string {
}
func (r *Registry) loadOne(plgDir, name string) bool {
return r.loadOneOpt(plgDir, name, false)
}
// loadOneOpt 是 loadOne 的显式版本。
//
// explicitStart=true 表示这是**agent 显式拉起**(plugin_start),
// 此时**忽略 auto_start**:插件声明"不自动启动"是"别在开机时拉起我",
// 不是"永远不许启动"。
//
// ★ 2026-10-18 补:在此之前**外部插件的 auto_start 完全不生效** ——
// Load 的目录扫描无条件调 loadOne,没有任何地方读 plugin.json 的
// auto_start。也就是说这个字段在 plg.json → plugin.json 一路写得出来,
// 内核却从不看它:声明 auto_start=false 的插件照样开机自启。
// (内置模块那条走的是 kernelboot/scheduler.go,与外部插件是两条路。)
func (r *Registry) loadOneOpt(plgDir, name string, explicitStart bool) bool {
if r.isDisabled(name) {
log.Printf("[plugin] %s is disabled, skipping", name)
r.mu.Lock()
@ -608,25 +593,6 @@ func (r *Registry) loadOneOpt(plgDir, name string, explicitStart bool) bool {
return false
}
// ③ auto_start 门(2026-10-18 补:此前外部插件从不检查这个字段)。
//
// plugin.json 的 auto_start=false 表示"**启用**但不随内核自启",
// 用于按需加载的插件(纯工具型,没人调用时不该占进程与工具槽位)。
//
// 三种启动形态在这里交汇:
//
// 自动启动 auto_start 缺省/true + 启动扫描 ⇒ 拉起
// 启用但不自启 auto_start=false + 启动扫描 ⇒ **跳过**(本门)
// 同上 + plugin_start ⇒ 拉起(explicitStart)
// 禁用 持久禁用清单 ⇒ 上面的 isDisabled 门挡住,连 plugin_start 也拒
//
// ★ explicitStart 是关键:声明 false 是"别在开机时拉起我",
// 不是"永远不许启动"。没有这个区分,按需插件就再也起不来了。
if !explicitStart && !r.shouldAutoStart(plgDir, name) {
log.Printf("[plugin] %s 声明 auto_start=false(按需加载),跳过启动扫描;用 plugin_start 可拉起", name)
return false
}
// 1) 查找工厂(init 自注册或 RegisterNative)
r.mu.RLock()
factory, hasFactory := r.factories[name]
@ -1098,7 +1064,7 @@ func (r *Registry) ReloadOne(name string) error {
r.detachPlugin(name)
r.closeDynamic(removed)
ok := r.loadOneOpt(plgDir, name, true)
ok := r.loadOne(plgDir, name)
if !ok {
return fmt.Errorf("reload plugin %s failed", name)
}
@ -1312,18 +1278,6 @@ func (r *Registry) DisablePlugin(name, by string) error {
func (r *Registry) EnablePlugin(name string) error { return r.Enable(name) }
// shouldAutoStart 读 plugin.json 的 auto_start(缺省 = true)。
//
// 读不到 manifest 时返回 true:宁可多启动一个(与旧行为一致),
// 也不要因为清单文件损坏而让插件静默不启动 —— 后者更难查。
func (r *Registry) shouldAutoStart(plgDir, name string) bool {
mft := readManifest(plgDir)
if mft == nil {
return true
}
return mft.ShouldAutoStart()
}
// isRuntimeStopped 报告插件是否处于**运行态关闭**(设计 §2.6.7.3)。
func (r *Registry) isRuntimeStopped(name string) bool {
r.mu.RLock()