From 55a2bf5a145d9d865205c81d76fbbb52e6ce3a50 Mon Sep 17 00:00:00 2001 From: anonsaber Date: Tue, 29 Sep 2026 10:14:03 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E4=BF=AE=E6=AD=A3=206=20=E5=A4=84?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=E8=A1=8C=E5=8F=B7=E9=94=9A=E7=82=B9=E6=BC=82?= =?UTF-8?q?=E7=A7=BB=EF=BC=8C=E8=A1=A5=201=20=E5=A4=84=E7=BC=BA=E5=A4=B1?= =?UTF-8?q?=E9=94=9A=E7=82=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 全量人工核对 44 个 `file.rs:行号` 锚点,发现并修正 6 处解析通过但指向错误行号的锚点 (`audit_anchors` 只验证锚点可解析,不验证该行是否承载文中所述内容): - src/main.rs 的 `--debug`/DEBUG_TOKEN 双因子读取块已从 96-109 上移到 82-92: deployment.md:62 (96→82)、:63 (97-100→82-89)、:65 (107-109→90-92), reference.md:228 (96-100→82-89) - SendMessage 结构体在 channel.rs:60 而非 :10(原指向 TELEGRAM_BACKOFF_BASE_MS 常量) - reference.md:206 生产路由合并点是 main.rs:180 而非 :194;205 的 setup 路由锚点同处校正 - design.md:739 的 llm 构造分支锚定 111-127 整段而非孤立的 :125 - deployment.md:69 补上 worker_authorized 自身定义点 (notify.rs:446), 原先只有 constant_time_eq (1136) 一个锚点,读者跳转后看不到被命名的符号 校验:GATE-DOCS PASS 6/6,ANCHOR AUDIT 250 line-refs / 0 errors, PATH AUDIT 363 path-refs / 0 errors,人工 dump 复核 44/44 锚点落点正确。 --- docs/deployment.md | 8 ++++---- docs/design.md | 4 ++-- docs/reference.md | 5 +++-- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/docs/deployment.md b/docs/deployment.md index 7696a6c..9ae73ed 100644 --- a/docs/deployment.md +++ b/docs/deployment.md @@ -59,14 +59,14 @@ **双因子启用条件(`SAF-DEBUG-GATE`,两者必须同时成立)** -1. 进程命令行必须带 `--debug`(读取于 `src/main.rs:96`)。 -2. `DEBUG_TOKEN` 环境变量必须存在且非空(读取于 `src/main.rs:97-100`)。 +1. 进程命令行必须带 `--debug`(读取于 `src/main.rs:82`)。 +2. `DEBUG_TOKEN` 环境变量必须存在且非空(读取于 `src/main.rs:82-89`)。 -缺一即不挂载:`debug_router()` 本身会构造出全部 7 条路由(`src/debug.rs:72-80`),但主入口**只在双因子成立时才合并它**(`src/notify.rs:1321-1322`)。所以未开启时 `/debug/*` 路由根本不存在,请求走 axum 兜底返回普通 `404 not found`——**不是** 401,也不会泄露「此路径存在」。开启成功时打一条 WARN 日志标记该面已打开(`src/main.rs:107-109`,`SAF-LOG-PURITY`:只记开启状态,从不记录 token 值)。 +缺一即不挂载:`debug_router()` 本身会构造出全部 7 条路由(`src/debug.rs:72-80`),但主入口**只在双因子成立时才合并它**(`src/notify.rs:1321-1322`)。所以未开启时 `/debug/*` 路由根本不存在,请求走 axum 兜底返回普通 `404 not found`——**不是** 401,也不会泄露「此路径存在」。开启成功时打一条 WARN 日志标记该面已打开(`src/main.rs:90-92`,`SAF-LOG-PURITY`:只记开启状态,从不记录 token 值)。 **鉴权** -7 条路由全部要求 `Authorization: Bearer `,统一走 `debug_authorized`(`src/debug.rs:45`),它委托生产同款 `worker_authorized`,因此令牌是**常数时间比较**(`src/notify.rs:1136`)。失败回 `401 unauthorized`,且不设 `Retry-After`(`src/debug.rs:52-54`)。 +7 条路由全部要求 `Authorization: Bearer `,统一走 `debug_authorized`(`src/debug.rs:45`),它委托生产同款 `worker_authorized`(`src/notify.rs:446`),因此令牌是**常数时间比较**(`src/notify.rs:1136`)。失败回 `401 unauthorized`,且不设 `Retry-After`(`src/debug.rs:52-54`)。 **7 条路由与预期状态码**(注册于 `src/debug.rs:72-80`,路径为字面量,无常量抽取) diff --git a/docs/design.md b/docs/design.md index ff658e4..5477631 100644 --- a/docs/design.md +++ b/docs/design.md @@ -692,7 +692,7 @@ Push 事件经 Streams 消费并投递到 Telegram,其关键路径交付语义 ### 11.4 已由代码回答的早期问题(不再待确认) 以下问题在设计阶段以 Q6–Q30 形式列出,**代码落地时已各自给出答案**,因此不再是"待确认项",此处只记结论: -- **消息格式**(Q6):出站只有 `send_text`(`src/channel.rs:134`),其载荷结构体 `SendMessage`(`src/channel.rs:80`)只有 `chat_id` + `text` 两个字段,**没有 `parse_mode`**——Telegram 收到后按纯文本渲染,既不用 HTML 也不用 MarkdownV2。 +- **消息格式**(Q6):出站只有 `send_text`(`src/channel.rs:114`),其载荷结构体 `SendMessage`(`src/channel.rs:60`)只有 `chat_id` + `text` 两个字段,**没有 `parse_mode`**——Telegram 收到后按纯文本渲染,既不用 HTML 也不用 MarkdownV2。 - **长邮件 / 原文直发**(Q7、Q29):不存在"正文超过 4000 字符不发全文"的策略。`read_email` 拉全文送 LLM;AI 失败时回退为前 300 字符且**无"已截断"标注**(见 §12.3/§12.5)。 - **附件**(Q8、Q28):完全未实现。领域模型只有 `has_attachment: bool`,出站只有 `sendMessage`,没有 `send_document` 也没有 `Blob/get`(见 §12.3)。 - **推送范围**(Q9):对账拉全量 `changes`,Bot 侧不做文件夹/发件人/关键词过滤,也没有 Sieve 依赖(Q11 因此无影响)。 @@ -736,7 +736,7 @@ LLM 能力只存在于 `src/ai.rs` 一个文件;**没有**配置 / 回退 / | 变量 | 类型 | 默认 | 用途 | |---|---|---|---| | `LLM_ENABLED` | bool | `false` | 总开关;默认关闭,未启用时不校验 `LLM_API_KEY`/`LLM_BASE_URL`/`LLM_MODEL` | -| `LLM_ALLOW_NET` | bool | `false` | 运行时出站许可;`LLM_ENABLED && LLM_ALLOW_NET` 同时为真才构造 `LlmClient`,否则 `llm` 字段为 `None`(`src/main.rs:125`) | +| `LLM_ALLOW_NET` | bool | `false` | 运行时出站许可;`LLM_ENABLED && LLM_ALLOW_NET` 同时为真才构造 `LlmClient`,否则 `llm` 字段为 `None`(`src/main.rs:111-127`) | | `LLM_API_KEY` | string | 可省略 | Bearer token;仅 `LLM_ENABLED=true` 时必填 | | `LLM_BASE_URL` | URL | 可省略 | 仅启用时必填,且必须 `https`,否则 `AiError::InvalidEndpoint` | | `LLM_MODEL` | string | 可省略 | 仅启用时必填;透传给 `/chat/completions` 的 `model` | diff --git a/docs/reference.md b/docs/reference.md index b4c63fd..9fb667f 100644 --- a/docs/reference.md +++ b/docs/reference.md @@ -202,7 +202,8 @@ string `"30"`: All HTTP API routes are registered in `router_with_worker_state_runtime_bootstrap_config` (`notify.rs:1276`), with the routes wired at `notify.rs:1305-1319`. The three static SPA routes in the last table row are the exception: they live in `web::router()` (`src/web.rs:19-24`) and -are merged into the production router at `src/main.rs:62` and `src/main.rs:194`. +are merged into the router via `.merge(web::router())`: the setup-mode router at `src/main.rs:62`, +the production router at `src/main.rs:180`. | Method | Path | Handler | |---|---|---| @@ -224,7 +225,7 @@ are merged into the production router at `src/main.rs:62` and `src/main.rs:194`. | GET | `/`, `/assets/config.js`, `/assets/styles.css` | `index` / `script` / `styles` | The remote-debug surface (`src/debug.rs:72-80`) is merged **only when the process is started -with `--debug` and `DEBUG_TOKEN` is non-empty** (`SAF-DEBUG-GATE`, `src/main.rs:96-100`, +with `--debug` and `DEBUG_TOKEN` is non-empty** (`SAF-DEBUG-GATE`, `src/main.rs:82-89`, `src/notify.rs:1321-1322`); otherwise none of these routes exist and requests fall through to axum's generic `404`, not a 401. All seven require `Authorization: Bearer `, checked by `debug_authorized` (`src/debug.rs:45`), which delegates to the production