feat(memory): 启动时自动播种面板配置文件(缺失才写、绝不覆盖)
主人 2026-10-07:「后端自动创建独立的面板配置文件要做」。 - 启动路径(wireMemoryTidy → applyMemoryTidyTuning 之后)若 $DATA_DIR/config/memory-tidy.json 不存在或全空白 => 写一份「当时生效值」 (十键:既有六键 + 频率四键),此后面板接管 - 已存在(非空)=> 跳过,该分支没有任何写盘语句;损坏 => WARN + 按 .env 跑、 一个字不写盘(不「修好它」) - 幂等(第二次启动必落到跳过分支);原子写(tmp 0600 + rename) - 落盘前完整性闸:缺键 / 非正周期 / 钟点越界 => WARN + 不落盘 - 值来自 TidyTuningSnapshot(先跑两个归一化再翻回正向键)=> 播种那一刻运行 行为零变化,有强断言(归一化后配置逐字相等) - 零新增依赖、零 env 键变更;5 个变异(含「让已存在走写盘」=> 红)
This commit is contained in:
1 parent
d680390300
commit
23b6e3fe1e
8 files changed
+1156
-6
No files matched your search
@@ -23,7 +23,10 @@ import (
|
||||
// (intervalSec / quietIntervalSec / quietStartHour / quietEndHour)。它是
|
||||
// `.env` 冻结(design/13 §2.1)之后新旋钮的唯一去处,**零新 env 键**;面板优先、
|
||||
// `.env` 兜底,键缺位或值不可用一律回落下一档并记 WARN(坏配置绝不能让自动档
|
||||
// 变成「无限制」,也不能让整理频率变成忙轮询)。
|
||||
// 变成「无限制」,也不能让整理频率变成忙轮询);
|
||||
// - **启动播种**(2026-10-07 追加,主人「后端**自动创建**独立的面板配置文件**要做**」):
|
||||
// 那个文件不存在时由后端自己写一份「当前生效值」进去(seedMemoryTidyPanel),
|
||||
// 使「面板优先」从第一次启动起就成立,而不是靠 `.env` 一直兜着。
|
||||
//
|
||||
// 刻意**不做**的一件事(design §4.1 F):
|
||||
// - 不把 sess-memorytidy 加进 flowPub 的图源白名单(默认关:整理是系统任务,
|
||||
@@ -31,6 +34,12 @@ import (
|
||||
func (a *app) wireMemoryTidy() error {
|
||||
cfg := memory.TidyConfigFromConfig(a.cfg.MemoryTidy)
|
||||
a.applyMemoryTidyTuning(&cfg)
|
||||
// 启动播种(主人 2026-10-07:「后端**自动创建**独立的面板配置文件**要做**」):
|
||||
// 文件不存在/空白 ⇒ 把**此刻的生效值**写成面板的一等来源,此后 `.env` 只兜底。
|
||||
// 放在 applyMemoryTidyTuning **之后**是刻意的:那一刻的 cfg 就是
|
||||
// 「面板 > `.env` > 代码默认」的结果(面板缺失时即 `.env` + 默认),播它 ⇒ 行为
|
||||
// 零变化。文件已存在(含损坏)⇒ 一个字节都不动(幂等,见 runtimeconfig.SeedMemoryTidy)。
|
||||
a.seedMemoryTidyPanel(cfg)
|
||||
svc, err := memory.NewTidyService(cfg, memory.TidyDeps{
|
||||
Store: a.memStore,
|
||||
Embedder: a.embedder,
|
||||
@@ -44,6 +53,27 @@ func (a *app) wireMemoryTidy() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// seedMemoryTidyPanel 在 `$DATA_DIR/config/memory-tidy.json` 缺失/空白时播种一份
|
||||
// 「当前生效值」快照(`memory.TidyTuningSnapshot`),使面板配置从第一次启动起就自足,
|
||||
// 而不是每次都靠 `.env` 兜。失败只记日志、**绝不阻断启动**:运行期仍按 `.env` +
|
||||
// 代码默认跑,行为与播种前逐字相同(与 materializeModels 同一口径)。
|
||||
//
|
||||
// 闸与 T1 的四键(ingestGate / t1Judge / t1PerWindow / t1WindowSec)在 `.env` 里
|
||||
// **没有出处**(`.env` 已冻结,它们只由这个面板文件与代码默认决定,见
|
||||
// wireMemoryReview 的三个 helper),而播种只发生在**面板文件不存在**时 —— 那正是
|
||||
// 「零值 + normalizeReviewConfig」这一条路径,因此这里给零值 ReviewConfig 就是
|
||||
// **当时**的生效值,不是猜的。审查开关本身(MEMORY_REVIEW_ENABLED)不在这十键里,
|
||||
// 因此不必为它去读一次 env。
|
||||
func (a *app) seedMemoryTidyPanel(tidy memory.TidyConfig) {
|
||||
path := runtimeconfig.DefaultMemoryTidyPath(resolveDataDir(a.cfg))
|
||||
log := logger.WithSource(a.log, "memory/tidy")
|
||||
// 播种函数自己会把「跳过 / 无法解析」记成带路径的日志(含 WARN),这里只报
|
||||
// 「该写却没写成」那一种 —— 不重复记同一条 WARN。
|
||||
if _, err := runtimeconfig.SeedMemoryTidy(path, memory.TidyTuningSnapshot(tidy, memory.ReviewConfig{}), log); err != nil {
|
||||
log.Warn("memory-tidy.json 播种失败(面板配置仍缺位,.env 继续兜底)", "path", path, "error", err)
|
||||
}
|
||||
}
|
||||
|
||||
// applyMemoryTidyTuning 把 `$DATA_DIR/config/memory-tidy.json` 叠到 env 侧的
|
||||
// TidyConfig 上(见 runtimeconfig.MemoryTidyTuning 的零值口径):
|
||||
// - 文件里**没写** autoApply ⇒ 保持代码默认(开);
|
||||
|
||||
Reference in new issue
Block a user