云端定时内容生产连环坑复盘:全绿不等于已发
一句话:无人值守流水线的验收标准是业务产物(main 上的提交/线上的页面),不是 CI 状态——「全绿」完全可以是兜底分支伪装出来的失败。
事实记录(不可修改区)
- 项目:蛛网之上「AIGC 快讯」,GitHub Actions 云端定时 workflow(
aigc-daily-news.yml,cron30 1 * * *UTC = 北京 9:30,claude-code-action + ofox 中转站) - 前情:2026-07-03 10:49 云端 workflow 上线,取代 07-02 的本机定时任务方案(本机方案从未经历无人值守运行,见 每日定时任务自动更新内容板块_首次自动化生产落地_v1);第 1、2 期均为人工发布
- 2026-07-04 上午发现官网快讯停在第 2 期;排查确认:schedule 从上线起一次都没被 GitHub 触发过,且整条自动路径从未真实执行过(此前唯一一次运行因当日文件已存在而跳过,显示成功)
- 07-04~05 共 7 次运行,连环暴露并修复 6 个独立故障点(下表);2026-07-05 08:03 第 3 期全自动上站(commit
c4ebc76),全链路首次无人工干预跑通 - 六个故障点:① GitHub schedule 从未自然触发(至归档时仍未发生过);② permissions 缺
id-token: write→OIDC 报错;③ 仓库未装 Claude GitHub App→需显式传github_token;④ allowedTools 只放行Bash(curl:*)→管道组合命令 12 次全拒、8 分钟空手收场;⑤ build 自检时 stamp-assets 改写跟踪文件→脏工作区卡死git pull --rebase,丢掉一期已生成的提交;⑥ 中转站余额为负→402(此前一次 $4 运行耗穿余额) - 成本实测:Fable 5 一次真实运行 $4.04(约 40 轮);切 Sonnet 5(单价约 1/3)后首跑 $7.26(178 轮,16 次权限拒绝)——更便宜的模型跑出了更贵的账单
- 数据来源:GitHub Actions 运行记录 + git log + claude-execution-output.json
排障过程
按发现顺序,每个坑修一轮、暴露下一个:
- schedule 不触发:workflow state=active、cron 正确、同仓库 deploy.yml 的 schedule 正常——排除配置问题,属 GitHub 对新 schedule 的已知不可靠行为。手动 dispatch 绕过,自然触发留观。
- OIDC 402→缺权限:claude-code-action@v1 硬性要求
id-token: write,补一行。 - 未装 GitHub App:action 默认走 App 的 OIDC 换 token;传
github_token: ${{ github.token }}跳过(本任务只需在 runner 里写一个文件,GITHUB_TOKEN 足够)。 - 白名单闷杀搜索:
curl … | grep …这类组合命令要求每一段都在 allowedTools 内,只放行 curl 等于全拒。扩容常用只读文本工具(node/jq/grep/sed/head/python3 等)后 Claude 才第一次真正搜到料。 - 脏工作区丢提交:
npm run build自检顺手改写了public/*/index.html(缓存戳脚本),后续git pull --rebase拒绝执行——期刊已生成、已 commit,却没能 push,白烧一次 API。push 前加git checkout -- .丢弃构建副产。 - 余额 402:报错只存在 runner 本地的执行输出 JSON 里,workflow 日志只有
is_error: true。加了「打印执行输出末尾」诊断步骤后一眼定位:402 Insufficient credits, balance $-0.05。充值后跑通。
结果分析
- 符合预期:6 个故障点全部修复;07-05 第 3 期从搜稿到上站全自动完成,内容质量合格(5 条真实可溯源)
- 未验证部分(诚实边界):① schedule 自然触发至今为零次,每一期都靠手动 dispatch,「定时」二字尚未兑现;② 成本纪律(
--max-turns 80+ prompt 内「凑足 5-8 条即收工」)是修复后新加的,压成本效果待下次运行验证
方法论沉淀(均为首次发现,暂时性结论)
⚠️ 全绿≠已发律(首次发现)
核心:带「不发」兜底分支的流水线,失败会伪装成成功——Claude 没产出文件时 verify 步骤走 exit 0,Actions 全绿,但什么都没发。验收和巡检必须盯业务产物,不看 CI 徽章。
来源:07-04 两次「成功」运行实际都是空手而归,徽章全绿。
操作规则:
- 巡检口诀:看 main 有没有当日
news(快讯)提交 / 线上页面日期,不看 Actions 状态; - 兜底分支不要静默
exit 0,至少echo出显著告警(有条件就发通知); - 「宁缺毋滥」闸门(见前档)与本律是一对:闸门允许不发,本律要求不发必须可见。
⚠️ 手动跑通会掩盖自动路径(对「人先跑通一遍」的边界修正,首次发现)
核心:前档主张「人先手动跑通再交给定时器」,本次暴露其盲区——手动发布让当日产物已存在,自动路径的幂等检查直接跳过,于是自动路径从未被执行过,而所有人都以为它验证过了。缺陷(OIDC/App/白名单/脏工作区)全部潜伏到第一次真实执行才连环引爆。
来源:07-03 那次 workflow 运行 8 秒「成功」,实为跳过;6 个坑全部在 07-04 首次真实执行时暴露。
操作规则:验证等级分三层分开记账,缺一不可:
- 手动跑通(人在环,验证流程设计);
- 自动路径真实执行(在产物不存在的条件下手动 dispatch 一次,验证权限/环境/脚本);
- 定时器自然触发(验证调度本身)。 本案例三层分别于 07-02、07-05 达成,第三层至今未达成。
⚠️ 黑盒 action 先接可观测性(首次发现)
核心:claude-code-action 的真实报错(API 402、denial 明细)只写在 runner 本地的 claude-execution-output.json,workflow 日志只给 is_error: true。盲修了三轮才想起把它打出来,一打出来 10 秒定位。
操作规则:接入任何黑盒 action,第一个 commit 就加 if: always() 的诊断步骤把其执行输出暴露到日志——排障顺序应是「先能看见,再动手修」。
⚠️ 换便宜模型≠更省(成本=单价×用量,首次发现)
核心:Sonnet 5 单价约为 Fable 5 的 1/3,首跑却花 $7.26 > $4.04——搜索行为更发散(爬 DuckDuckGo/Bing 结果页、for 循环批量查询),178 轮 vs 40 轮,用量放大 4 倍以上,把单价优势整个吃掉。
操作规则:
- agent 型任务换模型必须实测总成本,不能只看牌价;
- 给 agent 明确停止条件(「凑足 5-8 条立即收工」)和硬上限(
--max-turns); - 权限白名单拒绝会诱发换姿势重试,放大用量(本次 16 次拒绝)——白名单要么放够,要么在 prompt 里明说哪些路径走不通,别让它自己撞。
⭐⭐ 追记(2026-07-12):「schedule 不可靠」获二次验证
坑① 在另一仓库(typhoon-eye,台风数据每 15 分钟定时抓取)再次实证:每小时 4 班仅被放行约 1 班、整点连丢 4 班,GitHub 状态页全程 operational。该规律升 ⭐⭐ 二次验证,系统性兜底方案(外部 cron dispatch watchdog 型任务)见 B站Toy同步事故复盘_版本指纹与外部cron兜底_v1。
下次改进
- 观察次日 9:30 schedule 是否首次自然触发;连续不触发则换冷门分钟(如
47 1 * * *)再试 - 记录 max-turns + 成本纪律生效后的单次成本,更新本档成本结论的验证等级
- 考虑给「未产出」分支加通知渠道(而不只是日志告警)
关联文档
- 每日定时任务自动更新内容板块_首次自动化生产落地_v1 —— 前传:板块架构与「自动化只碰数据/人先跑通/宁缺毋滥」三律;本档修正其中「人先跑通」的验证盲区,并接续其三个待观察点
- 内容子项目构建时同步_独立仓库镜像进public_v1 —— 同族:内容自动上线管线;本次坑⑤(构建副产弄脏工作区)正发生在该管线的 build 环节
- ⚠️ B站Toy同步事故复盘_版本指纹与外部cron兜底_v1 —— 续证:坑①(schedule 不触发)的第二例,升二次验证;外部 cron 兜底方案落地并首跑补救实录
- OpenAI区域封锁与Worker就近执行陷阱_北美DO跳板_v1 —— 同族排查心法:云上黑盒不瞎试,先做定性实验(本档是可观测性先行,那档是双端对照定性)
- 内测反馈渠道上线_匿名兜底与422探针验证_v1 —— 同一「部署完≠已生效」纪律的轻量做法:上线后用必失败的校验请求(422 探针)独立核查新路由,零脏数据
- ⭐⭐ 成稿链接存进库没人读_写入方不等于展示方_v1 —— 本档「手动跑通会掩盖自动路径」的内容层再验(蛛网之上,2026-07-30):任务书正文里手写的「交付情况」替系统把成稿链接显示了,系统那条渲染路径缺失了两轮迭代都没人发现;升二次验证——凡「靠人手写补上」的地方,就是系统缺口的坐标