aliyun sensor server
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
# TamaBox-v4 项目长期笔记
|
||||
|
||||
## 审计/失败分级惯例(沿用用户偏好)
|
||||
|
||||
- 结论分级:P0/P1/P2,配 🔴(阻断级)/🟠(高)。给修复建议前先做根因取证与并行诊断。
|
||||
- 改代码前先出「方案/变更清单」获批准,再分批落地;用户倾向方案 A 或明确指定方向。
|
||||
- 工作场景用 `@scene#N:"名称"` 标记(如 `@scene#15:"日常开发"`)。
|
||||
- 用户常说「你先继续,后面我发现问题再和你说」→ 可自主推进,但重大问题仍要显式指出。
|
||||
|
||||
## 构建与测试(Windows 沙箱)
|
||||
|
||||
- **本机无 libwebp / GCC**,而 `chai2010/webp`(cgo)会挡住 `go build ./...`。
|
||||
必须用 overlay 把 `internal/storage/s3.go` 换成 `dev/s3stub/s3_stub.go`:
|
||||
```
|
||||
go build -overlay="C:/Users/Tamakyi Gekka/AppData/Local/Temp/tb-webpcheck/overlay.json" ./...
|
||||
go test -overlay="C:/Users/Tamakyi Gekka/AppData/Local/Temp/tb-webpcheck/overlay.json" ./...
|
||||
```
|
||||
(`dev/overlay.json` 里的路径指向 TAMAKY~1 短名,可能失效;用上面 Temp 里的那份。)
|
||||
- `internal/db` 的测试需要真实 PostgreSQL/MySQL(否则报 `Unknown database type: ""`),
|
||||
与业务改动无关,可跳过;`go vet` 已能覆盖其编译。
|
||||
- **`proxy.golang.org` 在本沙箱返回 Bad Gateway**:拉新依赖 / `go mod tidy` 前先
|
||||
`export GOPROXY=https://goproxy.cn,direct`。
|
||||
- `internal/security/censor/censor.go`、`internal/security/censor/text_test.go` 存在**升级前就有**的
|
||||
空格缩进(`gofmt -l` 会列出)。除非专门整理,否则不要顺手 gofmt,避免污染 diff。
|
||||
|
||||
## 内容审核架构(简洁版)
|
||||
|
||||
- 线上生效的审核通道是**七牛云**(`ai.qiniuapi.com/v3/text/censor`,scene=antispam);阿里云通道代码存在但 key 留空、不生效。
|
||||
- **通道可选**:`[security] text_censor_source = qiniu | aliyun | auto`(留空同 auto=七牛优先、阿里云兜底,即历史行为)。
|
||||
取值常量在 `conf`(`CensorSource*`),装配在 `censor.censorChain()`,启动校验在 `conf.validateTextCensorSource`。
|
||||
显式选通道却缺凭据会**启动报错**(避免运行期 fail-closed 导致整站不可用)。
|
||||
- 关键事实:七牛 `IsPass()` 只硬拦 politics/terrorism/porn,`review` 一律放行;
|
||||
七牛文本审核**不支持白名单**、自定义词库需提工单 → 服务端「拦得准不准」不可控。
|
||||
- 因此本项目把「是否拦截」从服务商 Pass 判定剥离,收敛到策略层:
|
||||
`internal/security/censor/policy.go`(档位裁决)+ `internal/security/moderation/moderation.go`(唯一入口 `Check`)。
|
||||
- **任何新增的文本审核调用点都必须走 `moderation.Check`**,不要再直接调 `censor.Text`,
|
||||
否则会绕过「审核严格度」档位。三场景:提问/回答、投票、私聊。
|
||||
- 语义约定:`LabelScore.Score` 统一归一化 0~1(七牛本身即 0~1;阿里云 2.0 无逐标签置信度,
|
||||
按 `riskLevel` 折算 high=1 / medium=0.6 / low=0.3,该响应内所有标签共用同一分值)。
|
||||
- 审核服务不可用时 **fail-closed**(拒绝提交)—— 这是既有行为,未经批准不要改成 fail-open。
|
||||
⚠️ 推论:**显式选定的通道一旦坏掉(账号未开通/欠费/权限不足),整站发布+私信会全部被拒**,现象隐蔽(只在日志)。
|
||||
|
||||
### 阿里云 green 通道(`/green/text/scan`, 2018-05-09)
|
||||
- 实现与上游 NekoBox 及阿里云官方 Go 示例**逐字节一致**;`TextScanRequest` 无独立 `Content` 字段,
|
||||
body 走内嵌 `RoaRequest.Content`。**SDK 的 ROA 默认 Content-Type 是 `application/octet-stream`**
|
||||
(`sdk/auth/roa_signature_composer.go:88`),现已显式 `SetContentType(requests.Json)` 对齐接口契约。
|
||||
- 已知故障:HTTP 200 + `data` 为空 → `"response data is empty"`。**该错误此前会吞掉顶层 code/msg/requestId**
|
||||
(唯一的根因线索),现已把 code/msg/requestId + 原始响应摘要(≤512 字符)写进错误。
|
||||
✅ 2026-09-10 实证根因:`code=596 "You have not opened Yundun Content Moderation Service"` ——
|
||||
阿里云回的是 **HTTP 200 + `success:false` + 无 data**,即「请求被拒也返回 200」。
|
||||
⚠️ **硬门槛:「内容安全 1.0」开通前提是账号完成企业实名认证**(官方 69806),个人认证账号**永远开不了**。
|
||||
开通入口是 `common-buy.aliyun.com/?commodityCode=cdi#/open`,不是产品介绍页 `aliyun.com/product/lvwang`。
|
||||
替代方案:迁「内容安全增强版 2.0」(`green-cip`,个人认证可开,但标签体系完全不同、需改代码),
|
||||
或退回 `auto`/`qiniu`。RAM 用户需 `AliyunYundunGreenWebFullAccess`;欠费停服同理。
|
||||
- `data[].code != 200`(任务级失败)仍 fail-closed 置 block,但现在会打 Warn ——
|
||||
否则「审核失败」与「真的违规」在日志里无法区分。
|
||||
- ⚠️ `SetContentType(requests.Json)` 已加,但**已证伪与上述故障无关**,保留原因仅是接口契约对齐。
|
||||
|
||||
## 文件工具陷阱(重要)
|
||||
|
||||
- `templates/user/moderation-strictness.html`:**用 Write/Edit 写它会被自动注入 `data-page-node-id` 属性**
|
||||
(每次一批新 id);**用 shell(sed)改则不会**。注入方是「文件工具触发的后处理钩子」,不是文件监听。
|
||||
→ **该文件今后只用 shell 修改**。相关断言(`templates/render_test.go`)已改成不依赖属性顺序的正则。
|
||||
- 往 gofmt 对齐组**中间**插 map 键,会把「拆分后剩余组」整组重新对齐 → 污染 diff。
|
||||
新键应插在组末尾或独立成组(前后留空行)。i18n 字典已因此返工过一次。
|
||||
|
||||
## 仓库状态
|
||||
- **git 仓库已损坏**(`.git/refs` 缺失、index 截断、对象库近乎空),用户明确要求「不要动 git」。
|
||||
备份/回滚一律用 tar.gz(排除 `.git`、`.workbuddy`),放在项目同级目录:
|
||||
`C:/OtherFiles/Github/TamaBox-v4-mainline-<描述>-<日期>.tar.gz`。
|
||||
Reference in New Issue
Block a user