feat(gateway): 配置只读事实面 + 后台思考行「档位/穿透」(契约 v0.68)

- 新增 GET /api/v1/admin/config-facts:记忆整理 7 键 + 安静时段 2 键的**进程生效值** + 声明默认值(反射读 default 标签,不读 .env)
- 面板:记忆整理卡 + 安静时段卡(Miuix 只读),文案按新语义「只服务主动搭话,不静默回复」
- 后台思考行加 urgency(**只能是下限**,存档不可分 high/critical)+ quietHoursBypassed(与既有 bypassed 是两件事)
- 红线实测:往响应里塞 JWT ⇒ TestAdminConfigFacts_NeverLeaksSecretValues 打红(连断言消息都把整个响应打出来了)
- 前端:configFacts 24 checks / ConfigFactsCards 29 / BackthinkUrgencyTags 19 全过
- 契约 v0.68(纯增量:B12 新端点 + B8 两字段 + §4.10 形状与语义 + §7.4-17 下限限定)
This commit is contained in:
AskaEth committed 2026-10-05 13:54:56 +08:00
1 parent a057a0f61f
commit 34cef95e17
25 files changed
+1741 -14

No files matched your search

+8
View File
@@ -375,7 +375,12 @@ func (s *Server) adminListBackthink(w http.ResponseWriter, r *http.Request) {
writeError(w, apperr.Wrap(apperr.ErrInternal, "backthink_failed", "failed to list backthink records"))
return
}
// 安静时段窗口取**运行时真正生效**的那一个(0/0 是「未填」而不是「没有安静时段」,
// 见 admin_config_facts.go 的 effectiveQuietHours —— 与 backthink 的 normalize 同口径),
// 否则 0/0 部署下会漏报真正的穿透。
quietStart, quietEnd := s.effectiveQuietHours()
for _, rec := range records {
quiet := backthinkQuietOutcomeOf(rec, quietStart, quietEnd)
out = append(out, AdminBackthinkItem{
ID: strconv.FormatInt(rec.ID, 10),
Trigger: rec.Trigger,
@@ -386,6 +391,9 @@ func (s *Server) adminListBackthink(w http.ResponseWriter, r *http.Request) {
Detail: rec.PushResult.Detail,
Bypassed: rec.PushResult.Bypassed,
At: rec.At.UnixMilli(),
// 紧急度下限 / 是否穿透安静时段(v0.68):只报存档可证的部分。
Urgency: quiet.urgency,
QuietHoursBypassed: quiet.bypassed,
})
}
writeJSON(w, http.StatusOK, out)