style(server): gofmt 注释规范 + init.sql 补 parent_session_id + 新增 ratelimit 判据

## 主体是 gofmt

`server/` 下 20 个文件的改动里,**142/147 行是注释与缩进** ——
Go 1.19+ 的 gofmt 把块注释里的 `//   x` 规范成 `//\tx`。
功能零变化。

## 一处实质:init.sql 补 parent_session_id

`ALTER TABLE sessions ADD COLUMN IF NOT EXISTS parent_session_id
 TEXT REFERENCES sessions(session_id)`

远端已在 `db/migrate.go` 的 `sqliteAddColumns` 结构迁移通道里加了同一列;
init.sql 是**全新库**的建库脚本,缺这列会让新库少一个字段。

- `IF NOT EXISTS` ⇒ 与结构迁移通道幂等,两者并存无害
- 默认空 = 根节点;**不据历史数据猜父子**(猜错会让线索拓扑失真,比没有更糟)

## 新增 handler/ratelimit_test.go(162 行)

速率限制的判据。此前这一块没有独立判据。

## 验证(本机实跑,非推断)

    go build ./...                              通过
    go vet ./internal/{handler,repo,db,sse}/   通过
    go test -count=1(handler/repo/db/sse/blob)
      handler  41.3s  ok
      repo    101.9s  ok
      db       1.1s  ok
      sse      0.01s ok
      blob     0.08s ok

`-count=1` 是刻意的:第一遍跑出来全是 `(cached)`,那种绿灯不算数。
This commit is contained in:
2026-10-05 09:26:07 +08:00
parent be9bfd3cd1
commit a8d6811cd7
21 changed files with 246 additions and 69 deletions

View File

@ -15,10 +15,10 @@ import (
生产上 `pi ↔ dsh` 一天跑了 **175 封**、正文 612KB,其中 **relay = 0** ——
全部是模型**主动**调 send_mail。而两道防线都只覆盖 `relay != ""` 那条路:
① 会话预算:`relay != ""` 才扣 ⇒ 主动发信不扣(且该会话 max_rounds=0=不限)
② maxRelayHops=5:`if relay != "" { ... }` ⇒ 根本不进那个分支
③ 插件自动转发守卫:日志明说"本轮不自动转发:来信方 dsh 是 Agent"
—— 守卫**工作正常**,但模型自己发的不受它管
① 会话预算:`relay != ""` 才扣 ⇒ 主动发信不扣(且该会话 max_rounds=0=不限)
② maxRelayHops=5:`if relay != "" { ... }` ⇒ 根本不进那个分支
③ 插件自动转发守卫:日志明说"本轮不自动转发:来信方 dsh 是 Agent"
—— 守卫**工作正常**,但模型自己发的不受它管
⇒ 三条全绕开。没有任何一层在数"两个 Agent 在没有人类参与的情况下连续往返了几次"。
@ -27,8 +27,8 @@ import (
从最新一封往前扫,**连续**的"发件方是 Agent 且收件方也是 Agent"的邮件计数,
遇到以下任一即停(= 归零):
· 人类发的信(`from_name` 是用户)
· 人类收的信(`to_name` 是用户)
· 人类发的信(`from_name` 是用户)
· 人类收的信(`to_name` 是用户)
"连续"与"人类参与即归零"这两点与 maxRelayHops 一致 —— 正常的
「Agent 干完活回一封、人类看一眼再派下一轮」不受影响;只掐住