每日「今日内容速览」推群通道
上线与验真报告

智游大别山 · 内部运维件 · 2026-10-12
老板令:以后每天固定推 目标群:智游大别山晨报群 全站唯一有意推业务群的通道

结论:通道已上线并完成端到端验真。今日(10-12)09:31:36 已补推成功, 4 条日刊内容送达「智游大别山晨报群」;每日 09:40 自动推送已挂上定时。 幂等、防重复、收口三道守卫全部实测 rc=0, 本机 / 本机镜像 / 服务器三方文件一致,双副本守卫 关键分裂 = 0。

一、通道拓扑(源头 → 管道 → 出口 → 守卫)

① 源头
日刊批次
公众号双号出稿 08:40 覆写
wechat_push/incoming/{luotian,zhiyou}_article_batch.json
字段:title / digest / link_url
② 管道
速览脚本
/home/ubuntu/group_daily_digest.py
合并两号 → 生成 markdown 速览 → 读群配置
40 9 * * * 经 run_job.sh 触发
③ 出口
企微群机器人
群配置 wechat_push/wecom_groups.json
当前启用群:智游大别山晨报群
发送成功留痕 errcode: 0
④ 守卫
三道闸
幂等闸(一天一条)
防重复守卫 09:42
群收口守卫 09:45

二、本轮修掉的三个真问题

① 幂等状态键名漂移 —— 会让守卫每天误报「漏推」

脚本原来把当日标记写成 last_date,而防重复守卫读的是 last_success_date → 取到 None → 每天 09:42 都会误报一次「疑似漏推」并告警到您个人企微。 这类 schema 漂移没有任何报错,只能靠实跑逮到。

处置:全站统一为 last_success_date / last_success_at(旧键只读兼容), 线上状态文件已迁移并备份;同时把 last_success_date 写进守卫的硬断言清单 —— 以后谁再改键名,守卫当场 rc=1。

② 防旧稿 —— 上游失败会把昨天的稿子当今天推

批次文件由上游 08:40 覆写。若上游当天失败,文件仍是往日的; 脚本不查就会把昨天的 4 条当成今天的内容推出去。

处置:推送前比对批次文件日期,非当日直接拒发并告警老板个人。 仅对「今天」生效(显式补推历史日期不受限),应急放行开关 DIGEST_ALLOW_STALE=1。实测:造一份昨日批次 → 拒发 rc=2 并落 decision=FAIL | 批次非当日(防旧稿)。

③ 试跑会污染「当日只推一次」的计数

「决定推送」的记账原本排在群门禁之前,导致试跑(DRY)也会记一笔 PUSH, 把防重复守卫的「当日 PUSH ≤ 1」判据顶爆。

处置:记账移到真正发送之前;试跑单独记 decision=DRY。 实测:试跑后审计里 decision=PUSH 行数 = 0。

三、守卫扩容:从「只守 1 个目标」到「守 2 个」

防重复守卫原先只守每日晨报一个目标,新通道等于没有防重复保护 —— 2026-09-23 那起「同一条发了很多次」的事故会在新脚本上原样重演。本轮同时补齐两处通用能力:

四、验真结果(全部为线上实测,非推断)

#验真项期望实测
1防重复守卫 · 干净态(2 目标)rc=0rc=0 ✓
2灵敏度:当日出现 2 次「决定推送」报警 rc=1rc=1 ✓
3灵敏度:把幂等闸整句删掉报警 rc=1rc=1 ✓
4灵敏度:闸被挪到发送之后(顺序错)报警 rc=1rc=1 ✓
5灵敏度:幂等键名被改报警 rc=1rc=1 ✓
6无误伤:晨报目标仍全绿rc=0rc=0 ✓
7豁免生效:审计含「批次非当日」不报漏推 rc=0rc=0 ✓
8反证:同样过期、但无豁免理由报漏推 rc=1rc=1 ✓(证明豁免非无条件放行)
9脚本:同日第二次运行幂等跳过 rc=0rc=0 ✓
10脚本:昨日批次(防旧稿)拒发 rc=2rc=2 ✓
11脚本:当日批次为空(无内容)拒发 rc=2rc=2 ✓
12脚本:试跑不落 PUSH 计数PUSH=00 ✓
13群推送收口守卫 / 防重叠守卫rc=0 / 需处理 0rc=0 · 0 ✓
14双副本一致性守卫关键分裂 = 00 ✓,镜像缺失/多余 0/0

五、口径与开关(备忘)

静音DIGEST_GROUP_PUSH=0 —— 一条环境变量整体静音,不改码。

试跑DIGEST_DRY=1 —— 只打印不发送,落 decision=DRY。

补推python3 group_daily_digest.py 2026-10-12 —— 指定日期补推。

强推--force —— 绕幂等闸(会如实记 2 次 PUSH,守卫会报,属预期)。

与全站群总闸的关系:wecom_app.json 的 group_enabled=false 管的是 「企微应用推群」,本通道走的是群机器人 webhook,不受该总闸约束 —— 这是本通道能推群、 而晨报仍静音的原因,两者口径不冲突。

六、回滚点与文件指纹

回滚点(改前原样备份):/home/ubuntu/backups/20261012_digestguard_pre/

文件改前改后(三方一致)
group_daily_digest.pyfbd54cbb…94aa14c3…
push_dup_guard.pyf21d8fe3…4bc72439…
dual_copy_guard.pyf23353e2…1524bf16…

三份文件均满足:本机 = 本机镜像 = 服务器(md5 逐字节一致);换行符 CRLF = 0;语法编译通过。

本轮留痕