Commit Graph

124 Commits

Author SHA1 Message Date
anonsaber c5bc7b8d82 fix(notify): /ready JMAP 探针对齐真实客户端(Basic 认证 + 路径归一)
架构师复核指出两点会致全站不可用的缺陷(notify.rs):

- 探针未带认证:真实 jmap_client 以 .credentials() 取 session,Stalwart
  session 端点需认证;无认证必 401 → /ready 永久 503 → ingress 停止路由。
  改为从 business_runtime 快照取 jmap_username/jmap_password,
  basic_auth 随请求发送(零新增依赖,凭据仅入请求头,绝不日志)。
- session URL 未归一:配置若是裸 origin,GET 根路径必 404 → 误报。
  改为复用 normalize_session_url(client.rs 改为 pub(crate))并请求
  标准 /.well-known/jmap,与 JmapClientBackend::connect_with_runtime 同路径。

顺带:两探针 tokio::join! 并行,/ready 最坏耗时 3s→3s(原 6s)。

门禁 4/4 绿(45 passed, 0 failed, 1 ignored)。
2026-09-28 10:37:22 +08:00
anonsaber c0aab5e966 feat(notify): /ready 接入 JMAP session 与 Telegram getMe 端到端探测
ARCH-READY-BASELINE 从「配置完整性 + Redis 可达性」升级为端到端就绪:

- PROBE_TIMEOUT=3000ms 各探针独立超时(notify.rs:69)
- cached_jmap_session_url / cached_bot_token 先克隆后 await,
  避免跨 .await 持有 RwLockReadGuard(非 Send)
- probe_jmap_session:GET JMAP session URL,error_for_status
- probe_telegram_get_me:bot token 仅用于拼 URL,绝不日志
- ready():四者全过返 200 + 就绪报告 JSON(jmap/telegram 真实结果),
  任一失败 503 + Retry-After: 30(标准错误 envelope)
- 探针只读、无状态写入;token 永不回显(SAF-NO-SECRET-ECHO)

门禁:fmt / check / clippy / test 4/4 绿(45 passed, 0 failed, 1 ignored)。
2026-09-28 10:15:52 +08:00
anonsaber a39ebcf9d1 feat(worker): safelist 纳入 push/register 与 push/disable
网关白名单此前无条件 fail-closed,后端注册的 18 条路由中只有
POST /api/push/register 与 POST /api/push/disable 两条需要业务流量却未
被转发,导致 PWA 订阅/退订必须绕过网关直连后端。

- SAFE_ROUTES 12 → 14 条(backends.js:9-24)
- ROUTE_METHODS 同步补两条 POST(index.js:40-55)
- 头注释路由清单同步
- backends.test.js 转发集合断言补齐两条
- index.test.js 新增转发端到端用例(含鉴权头透传路径)

单入口边界:两条路由仍经 SAFE_ROUTES 无条件校验,未放宽白名单语义。
2026-09-28 10:02:18 +08:00
anonsaber e35cc64ce3 docs: 清理废弃/虚构条目,新增 retired.md 独立废弃记录
新增 docs/retired.md(114 行)作为唯一废弃/虚构条目登记处:
- 12 条未采用的路线(teloxide / feature 集 / teloxide-core 回退 /
  grammers / BotError 六个未落地变体 / 速率桶+429 分支 / 多步 FSM /
  模块子树拆分 / telegram_dispatch 测试 / docker healthcheck 示例)
- 原 teloxide 候选对比评估记录 + FSM 五态状态表(保留决策依据,非当前事实)
- 24 条虚构条目(文档曾写、src/ 从未有):幽灵模块树、delivery:pending 键、
  check_config_reload、PushVerification、CancellationToken、Preview、
  LlmErr、四个不存在的 LLM 环境变量、llm.call span、熔断/半开设计等
- 2 条已删除文档(docs/todo.md、HANDOFF.md,后者从未进入 git 历史)
- 3 步重启流程

docs/design.md 850 → 764 行:17 处目标形态改写为可核实的当前事实。
重点:§4 压缩并指向 retired.md;§5.2 补 Channel/Notifier/MessageAdapter
三 trait 零实现;§6 树改为真实 12 文件结构;§8.1 换成真实 src/error.rs
(原目标形态 6 变体整体移至 retired.md);§8.3 明标无 tracing/metrics/
优雅关闭;§10.0 GATE-P0 已过;§10.5 明标 notify.rs 平铺单文件;
§11.4-11.7 的 17 条 Q 收敛为一节(均已由已实现代码回答);
§12 全节重写(LlmClient 非 AiClient、AiError 3 变体、无熔断、
无附件、无长邮件保护、read_email 实取全文送 LLM);§12.8/§12.9 合并。

docs/reference.md:删 delivery:pending:{stream} 换真实 stalwart:{jmap,telegram}
流名;删 cloudflare-worker/src/commands.rs 论断;键锚点校正;补网关
fail-closed 无开关说明。

AGENTS.md:§6 注册 retired.md;新增 §6.3 幽灵名规则(文档出现的模块/函数/
键必须是 src/ 真实存在,要留不存在的名字必须同时登记 retired.md);
teloxide 专属措辞通用化为「渠道层不引入第三方 Bot 框架类型」;
保留「不得声称使用未引入依赖」约束。

docs/roadmap.md:item 2/26 按真实数字重写(18 条路由 12 条经 Worker 转发,
不转发的 6 条中仅 2 条需业务直连);决策待定补处置建议。
README / README.zh-CN 阅读表加 retired.md,保持 1:1 对等。

待决策项收敛结论:真剩 2 项(Q-DEP-A Worker 白名单、Q-DEP-B 平台选型),
均为上线时运维选择,不影响代码结构与门禁,可挂起不产生技术债。

src/、web/、cloudflare-worker/ 零改动。基线仍 45 passed / 0 failed / 1 ignored。
2026-09-27 21:53:58 +08:00
anonsaber 0e10591534 docs(design): §8.1 BotError 目标形态代码块加消歧注释
Q5 一致处理:代码块内补一行「// 目标形态(teloxide 未引入)」,与上方免责互证,消除重构后唯一例外。
2026-09-27 20:49:53 +08:00
anonsaber 24cfbb45b0 docs: 重构文档体系 — README 瘦身中英对等 + 新增 reference.md 权威事实表
- README.md / README.zh-CN.md 瘦身至 ~100 行,五节 1:1 对等(是什么/5分钟/配置入口/安全边界/去哪读更多)
- 新增 docs/reference.md:Redis 键+TTL+写者+读者、错误 envelope+Retry-After、后端路由与网关白名单矩阵、env 三层等单一权威表(顶部 verified against ed93358)
- 新增 docs/roadmap.md 取代 docs/todo.md(只放缺口/阻塞/阶段目标/待决策)
- docs/design.md 保留架构语义,可查表改引 reference.md;修正 /search 未实现、XAUTOCLAIM 阈值矛盾、teloxide 幽灵引用等 9 处标注
- docs/deployment.md §8.1 重写,删除依赖不存在子命令/curl 的必然失败 healthcheck 示例
- AGENTS.md §6 登记 reference.md/roadmap.md + 冲突仲裁「以 reference.md 为准」+ 中英同轮同步/公共 API 变更规则
2026-09-27 18:55:38 +08:00
anonsaber ed93358e29 feat(notify): unify /ready not-ready 503 into the error envelope
- GET /ready: ready -> 200 + diagnostic report (unchanged success body);
  not ready -> 503 + {"error":"service_unavailable","request_id":id}
  + Retry-After: 30, consistent with the other public entry points
- drop the legacy {"status":"not_ready"} diagnostic block from the 503 body
  (backward compatibility not required)
- HTTP 200/503 semantics preserved, so Uptime Kuma HTTP(s) monitors
  (status-code based) keep working
- sync docs: README.md, README.zh-CN.md, docs/design.md, docs/deployment.md,
  AGENTS.md, docs/todo.md
2026-09-27 13:11:29 +08:00
anonsaber a8fad19daa docs: default README to English, reconcile docs, drop HANDOFF
- README.md is now English; add README.zh-CN.md with cross-links; both versions
  cover the same 40 sections and the same key facts
- correct stale docs/design.md 10.5.1 and docs/todo.md to the current code
  (XAUTOCLAIM threshold, malformed-entry ACK, error envelope now done)
- replace the temporary HANDOFF.md with docs/todo.md (unfinished work + blockers)
- adjust docs/deployment.md and AGENTS.md accordingly
2026-09-27 12:56:04 +08:00
anonsaber 6868d47cd0 feat(web): add SPA i18n with browser-language detection (zh/en, default en)
- detect locale from navigator.language (zh* -> zh, otherwise en) at startup;
  <html lang> switches accordingly; English is the default
- index.html carries English default text plus data-i18n /
  data-i18n-placeholder / data-i18n-aria attributes
- config.js holds inline en/zh dictionaries, t(key, vars) and detectLocale();
  dynamic Chinese strings become t() calls with {var} interpolation
- no new asset files (src/web.rs serves only config.js and styles.css);
  stays a build-less vanilla-JS single page
- config.test.mjs updated to the English defaults; adds dictionary key-parity
  and markup key-coverage tests
2026-09-27 12:53:36 +08:00
anonsaber f16b747672 feat(notify): unify public-route error envelope and add push route tests
- all public write routes now return {"error":code,"request_id":id};
  retryable 503 responses add Retry-After: 30; 204 and success bodies unchanged
- GET /ready keeps its structured diagnostic JSON (Uptime Kuma runtime contract)
- add HTTP tests for the push register/disable routes
2026-09-27 12:53:22 +08:00
anonsaber 309a38c503 fix(worker,state,jmap,config): close independent-review findings
- worker/state: paginate Email/changes by widening maxChanges on the same
  sinceState (jmap-client 0.4.2 has no upToId) to avoid skipping a batch when
  advancing per page; make dedup+enqueue atomic via claim_dedup_and_enqueue
  (Lua SET NX EX then XADD); scale the XAUTOCLAIM idle threshold by batch size;
  XACK payload-less malformed stream entries out of the PEL via ack_malformed;
  fail closed on unknown streams (Err); tighten SET NX EX TTL to .max(1);
  derive the CSPRNG fallback owner-token from time+PID+counter instead of a
  constant; clear the push verification digest on push:disable
- worker: /help menu now lists only the consent triggers the parser accepts
- jmap/config: complete client and configuration validation
2026-09-27 12:53:05 +08:00
anonsaber 4f5eb9293d chore(worker): rename proxy to lb and ignore build cache
- cloudflare-worker: unify terminology proxy -> lb/forward
  (PROXIED_ROUTES -> LB_ROUTES, proxyWithFailover -> forwardWithFailover,
  proxy.js -> lb.js, related tests and README); renames/wording only, no behavior change
- Dockerfile: crates.io index mirror rsproxy.cn -> mirrors.ustc.edu.cn
- .gitignore: ignore build verification cache .gate-cache/ (cargo registry + rustup, ~1.5G)
2026-09-27 12:52:55 +08:00
anonsaber 956ef6a1d3 feat(config): add global Redis-backed enable switch 2026-09-25 20:11:35 +08:00
anonsaber a5710331fa docs(hoststack): add native Rust deployment config 2026-09-25 18:51:36 +08:00
anonsaber 4ecfa44485 fix(redis): install explicit rustls crypto provider 2026-09-25 18:02:21 +08:00
anonsaber a57cb4f75d fix(redis): enable TLS for Upstash connections 2026-09-25 17:45:24 +08:00
anonsaber e18cecca16 refactor: remove legacy project identity 2026-09-25 10:40:10 +08:00
anonsaber c75858fda0 refactor: rename project to MessageWeave 2026-09-25 10:29:18 +08:00
anonsaber 8c32892206 fix: preserve desktop setup card width 2026-09-25 10:24:43 +08:00
anonsaber 9064fc5f1d fix: hide admin authorization in setup mode 2026-09-25 10:05:47 +08:00
anonsaber 8a24ec7e9e fix: report all missing setup requirements 2026-09-25 09:42:15 +08:00
anonsaber e5ec3aef4c feat: provide configuration setup mode 2026-09-25 09:30:45 +08:00
anonsaber fc43c6bf93 build: use rsproxy for container dependencies 2026-09-25 09:21:43 +08:00
anonsaber dceecaf2f4 feat: initial MessageWeave release 2026-09-25 09:14:04 +08:00