Kindness-Kismet:Stelliberty 改用 effective.yaml 供规则页读取,并修复基线缺失时规则编辑静默回退

在 stelliberty PR 128 中,作者关闭该 PR,说明底层问题已在 stable 上通过 #129 用另一种方式修复:PR 的做法会在规则页每次加载时重新执行用户覆写脚本(YAML 合并与 JS 的 main(config)),每次保存规则最多执行 3 次、且仅用于显示,同时仍会遗漏在更后面的流水线阶段由链式代理引入的代理组。改为把「原始 → 覆写 → 链式代理」之后、规则覆写之前的中间产物持久化为 effective.yaml(与 original.yaml、runtime.yaml 并列),规则页直接读取该文件,不再额外执行覆写,链式代理的分组也包含在内。后续提交还补上一个相关漏洞:升级或首次启动、基线尚未生成时,规则编辑会静默回退到原始订阅内容,可能把重复规则和错乱的规则顺序推给内核,该页面在基线生成前改为只读。作者称已用带 YAML 覆写的订阅端到端验证:覆写引入的规则可见、覆写引入的代理组可作为自定义规则出口选择、停用内置规则仍可恢复。

作者原文

Thanks for spotting this bug. The underlying issue is now fixed on stable via #129, using a different approach, so I'm closing this PR.

Why a different approach

This PR re-runs the override engine inside RuleOverrideService.LoadCurrent(). That means user override scripts (YAML merge + JS main(config)) execute again on every rule-page load — up to 3 times per rule save — purely for display. It also still misses proxy groups introduced by chain proxies, since those are applied in a later pipeline stage.

What was done instead

The runtime pipeline is: original -> overrides -> chain proxies -> rule overrides -> runtime params. The stage right before rule overrides is exactly what the rule page needs, and it already existed as a local variable inside SelectedSubscriptionRuntimeGenerator. It is now persisted as effective.yaml next to original.yaml and runtime.yaml, and the rule page reads that file. Zero extra override execution, and chain-proxy groups are included too.

A follow-up commit also closed a related hole: before the baseline exists (upgrade, first launch), rule editing used to silently fall back to raw subscription content, which could push duplicate rules and a corrupted rule order into the core. The page is now read-only until the baseline is generated.

Verified end to end with a subscription carrying a YAML override: override-introduced rules now appear, override-introduced proxy groups are selectable as custom-rule outbounds, and disabling a builtin rule remains reversible.