feat(gateway): 面板人工加记忆钉 long + skill 解析去回显 + 可观测读侧脱敏
三处遗留(M37/M38/M39)同落 internal/services/gateway:
① adminAddMemory 显式传 RetentionTier=long(主人 2026-10-26 裁定「人工动作
默认 long」)。此前不传档位,面板典型输入(短寒暄/一次性祈使/时效查询/句首
时点/进行中)会被 resolveRetention 判 temp 并写 7 天有效期 —— 主人在面板上
亲手加的记忆会静默消失。只钉这一条入口,Store.Add 默认仍由规则判定
(自动抽取路径不放宽)。
② adminInstallSkillPlugin 解析失败不再打 err.Error():新建
admin_plugins_skill_error.go,把失败折叠成「类别(yaml_syntax /
yaml_type_mismatch / skill_invalid / skill_source)+ 行列号」,日志与 400
响应用同一份摘要。解码器会把出错值前 7 个字符嵌进错误串(M38 #17),
原样日志等于把上传内容写进 viewer 可读的日志面。
③ 读侧脱敏走既有 helper,不另写一套:
- adminLogOf 的 msg 过 trace.RedactText(与写侧同一函数);
- adminSpanOf 先过 trace.SanitizeRecord(REST 尾部与 observability_trace
推送帧在同一处收口)。⚠️ 有意改变 admin 响应内容:props 变白名单投影 +
omitted 摘要;字段名与帧形状不变。行数/级别/时间戳/来源、span 的
status/耗时/时间/名字一律保住。
测试(每条都验过「删掉实现 ⇒ FAIL」):
- 面板加记忆 ⇒ 落库 (retention_tier='long', expires_at='');对照组证明同一句
内容走 Store.Add 仍判 temp;
- 非法 YAML 含哨兵 ⇒ 响应与日志均无哨兵、都有类别与 line 2(内联/文件/语法/
来源四类);
- 日志页 msg 含 sk- 形状凭据 ⇒ [redacted],level/source/time 与非敏感正文保留;
- trace 响应 props 正文 ⇒ omitted Digest、args_summary 打码,排障字段原样。
验收:go build ./... / go vet ./... 全绿;go test -count=1 -race
./internal/services/gateway/... 全绿。未 push(按任务口径)。
This commit is contained in:
1 parent
a697fa0a1e
commit
fa5d3d23bf
8 files changed
+686
-12
No files matched your search
@@ -9,6 +9,7 @@ import (
|
||||
|
||||
apperr "git.yeij.top/AskaEth/Cyrene_v2/internal/errors"
|
||||
"git.yeij.top/AskaEth/Cyrene_v2/internal/logger"
|
||||
"git.yeij.top/AskaEth/Cyrene_v2/internal/runtime/trace"
|
||||
)
|
||||
|
||||
// 日志尾部端点的调参。编译期常量(项目规范 §10)。
|
||||
@@ -91,12 +92,24 @@ func (s *Server) adminObservabilityLogs(w http.ResponseWriter, r *http.Request)
|
||||
}
|
||||
|
||||
// adminLogOf 把捕获的日志条目映射为驼峰式管理线上结构。
|
||||
//
|
||||
// 🔴 读侧脱敏(M42 #3):`msg` 是日志正文,也是唯一可能夹带凭据/正文的字段
|
||||
// (本仓有过「把上游报文整段打进日志」的先例),因此出面板前过一遍
|
||||
// `trace.RedactText` —— 与写侧(trace.JSONRecorder)**同一个函数**,不另写一套;
|
||||
// 两套脱敏必然漂移,而漂移的方向总是「其中一面开始原样吐凭据」。
|
||||
//
|
||||
// 排障字段一律保住:`time`(RFC3339)、`level`、`source`(模块来源标签,编译期
|
||||
// 常量构成,不含内容)原样透出,且 `msg` 的打码不改变条目条数、排序与级别过滤
|
||||
// —— 面板因此照旧可诊断「谁在什么时候按什么级别报了哪一类错」。
|
||||
//
|
||||
// 注意 `RedactText` 同时按 `maxSummaryRunes` 截断(与出图/落盘同一口径):超长
|
||||
// 正文会带省略号。这是复用同一个 helper 的既定代价,远小于「凭据原样上面板」。
|
||||
func adminLogOf(e logger.Entry) AdminLogEntry {
|
||||
return AdminLogEntry{
|
||||
Time: e.Time.UTC().Format(time.RFC3339),
|
||||
Level: e.Level,
|
||||
Source: e.Source,
|
||||
Msg: e.Msg,
|
||||
Msg: trace.RedactText(e.Msg),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user