长期夜间编程平台方案选型报告
访问时间:2026-05-13 10:33 CST
研究对象:本机 NixOS + DeepKr 多仓库 + Codex/Claude Code/AI worker 的无人值守夜间编程平台。
结论级别:方案选型与迁移路线;不是继续修补 `night_tick.py` 的局部排障记录。
1. 执行摘要
核心结论: 当前夜间编程失败不是单点 bug,而是把 cron、队列、状态恢复、AI worker、验证、提交、通知揉进一个轻量脚本后产生的系统性失效。长期方案应升级为:调度器 → durable workflow engine → 隔离 worktree worker → artifact contract → reducer/merge queue → validation gates → local commit/report/dashboard → human-in-loop。
推荐选型:
- **主控引擎:Temporal(优先)**。原因是它把 durable execution、activity retry、workflow history、query/signal、worker/task queue、Web UI 这些能力放在同一个一致模型里;AI 编码 CLI 这类外部副作用应封装为 Activity,而不是写在 Workflow 纯逻辑里。
- **轻量队列层:BullMQ/Redis(可作为 Phase 1 或局部队列)**。原因是用户已有 TypeScript/Bun 生态,BullMQ 的 retry/backoff/stalled job/flows 对“单机先跑起来”很合适;但它不是完整 durable workflow engine,需要自行补状态机、审计日志和人机介入。
- **LangGraph:作为 agent 内部可恢复图,而不是全局编排内核**。它适合 checkpoint、interrupt、human-in-loop、time-travel;但本地多仓库 worker、git worktree、验证和提交队列仍要由外层平台治理。
- **Airflow/Dagster/Prefect:不作为首选主控。** 它们强在数据/作业编排、UI、schedule 和 retry,但对 AI 代码修改的隔离、diff reducer、工作树治理不是原生问题域。
立即行动:
- 保持 `night-admin-dev-queue` 暂停,不直接 resume。
- 先做 P0 止血:修 `in_progress` 阻塞、stale lock、`.env.example` 误判、Web 脏工作树 reducer/commit。
- 用 1 周做 Temporal/BullMQ 双轨原型:同一条 `admin-01` 任务端到端跑通,比较恢复、可观测性和维护成本。
- 迁移到“任务 artifact 合同 + 独立 worktree + reviewer gate + local commit”后,再恢复夜间批量。
风险提示: Temporal 不是魔法:Workflow 必须保持 deterministic,所有 `codex exec`、git、文件系统、浏览器测试都必须做成 Activity,并且 Activity 要幂等或可补偿。否则会把旧脚本的隐患搬进新引擎。
2. 问题定义
2.1 当前事实
当前夜间编程管线的关键状态:
- Hermes Cron job `night-admin-dev-queue`:paused / disabled,repeat 8/16。
- Admin 队列:14 个任务,completed 1,stale in_progress 1,failed 1,pending 11。
- `admin-00-foundation` 已完成并本地提交:`cfe21f1 feat(admin): 创建后台管理系统前端骨架`。
- `admin-01-shell-navigation` 标为 `in_progress`,但无实际 `night_tick` / `codex exec` 进程。
- `admin-02-api-auth-openapi` 标为 failed,根因是 pollution scan 把 `.env.example` 当污染文件。
- Web Browser E2E 夜间队列 3/3 完成但未提交,形成脏工作树风险。
- `night_tick.py` 的状态机缺陷:未优先阻塞已有 `in_progress`,会越过 stale 状态继续消费 pending。
- 通知层另有 Weixin delivery error,但它不是本地任务失败根因。
2.2 研究问题
需要回答的问题不是“怎么让 cron 再跑一次”,而是:
- 长期无人值守 AI 编程应使用哪类 durable workflow / queue / scheduler?
- AI coding worker 应如何隔离,避免 diff 混杂、污染主工作树和不可回滚?
- 如何设计 reducer、validation gate、本地 commit、人工介入和 dashboard?
- 在本机 NixOS + 多 repo + Codex/Claude Code 的实际约束下,分阶段迁移路线是什么?
2.3 边界
- 不自动 push;validation 通过后只允许 local commit。
- 不未经人工同意安装依赖。
- Codex/Claude Code 等 AI CLI 是 worker,不是 workflow engine。
- Cron/systemd timer/GitHub Actions 只能做 trigger,不能承担 durable state machine。
- 报告面向长期平台建设;短期止血仅作为 Phase 0。
3. 证据矩阵
| 声明 | 来源 A | 来源 B | 一致性 | 备注 |
|---|---|---|---|---|
| Cron/timer 适合触发,不适合承载 durable workflow 状态机 | systemd.timer 文档说明 timer 触发 unit;GitHub Actions schedule 文档说明 cron 触发 workflow | Airflow 文档把 schedule 与 DAG run/task state 分离 | ✅ | 当前把 cron 和状态机混在脚本里是结构问题 |
| 长期无人值守任务需要持久化状态、重试、历史和恢复 | Temporal durable execution / retry policy | LangGraph persistence / fault-tolerance / pending writes | ✅ | Temporal 更偏通用工作流;LangGraph 更偏 agent graph |
| 外部副作用必须与可重放编排逻辑隔离 | Temporal TS 文档:Workflow deterministic,外部状态通过 Activities | Celery 文档:任务需幂等、ack/retry 会导致重复执行 | ✅ | AI CLI、git、浏览器测试都应是 Activity/Task |
| 简单 queue 可以做 retry/backoff,但不是完整平台 | BullMQ retry/backoff + flows | Celery retry/states/canvas/chords | ✅ | 需要另补审计、人工介入、artifact 合同 |
| AI 编码 worker 必须运行在受限/隔离环境 | Codex sandboxing 文档 | OpenHands Docker Runtime / SWE-agent ACI 思路 | ✅ | 本地最小可行隔离是 git worktree + sandbox 权限 |
| git worktree 是多任务本地隔离基础 | Git 官方 worktree 文档 | Aider 文档强调 git auto-commit/dirty separation | ✅ | worktree 解决“同一工作树混 diff”的 P0 风险 |
| Airflow/Dagster/Prefect 强在 workflow UI/作业编排,但不是 AI diff reducer 原生工具 | Airflow DAG/scheduler 文档 | Dagster retries / Prefect states 文档 | ✅ | 可借鉴 UI/状态模型,不建议作为首选内核 |
| Cloudflare 可用于发布报告产物 | Cloudflare Pages Direct Upload / Wrangler Pages | Workers Custom Domains 文档 | ✅ | 本报告采用 Worker custom domain 部署 HTML |
4. 来源清单
| 类型 | 来源 | URL | 访问时间 | 可信度 |
|---|---|---|---|---|
| 官方文档 | Temporal Retry Policies | https://docs.temporal.io/encyclopedia/retry-policies | 2026-05-13 10:33 CST | 高 |
| 官方博客 | Temporal Durable Execution | https://temporal.io/blog/what-is-durable-execution | 2026-05-13 10:33 CST | 高 |
| 官方文档 | Temporal TypeScript Core Application | https://docs.temporal.io/develop/typescript/core-application | 2026-05-13 10:33 CST | 高 |
| 官方文档 | LangGraph Durable Execution | https://docs.langchain.com/oss/python/langgraph/durable-execution | 2026-05-13 10:33 CST | 高 |
| 官方文档 | LangGraph Persistence | https://docs.langchain.com/oss/python/langgraph/persistence | 2026-05-13 10:33 CST | 高 |
| 官方文档 | BullMQ Retrying Failing Jobs | https://docs.bullmq.io/guide/retrying-failing-jobs | 2026-05-13 10:33 CST | 高 |
| 官方文档 | BullMQ Flows | https://docs.bullmq.io/guide/flows | 2026-05-13 10:33 CST | 高 |
| 官方文档 | Celery Tasks / Retry / States | https://docs.celeryq.dev/en/stable/userguide/tasks.html | 2026-05-13 10:33 CST | 高 |
| 官方文档 | Celery Canvas | https://docs.celeryq.dev/en/stable/userguide/canvas.html | 2026-05-13 10:33 CST | 高 |
| 官方文档 | Prefect States | https://docs.prefect.io/v3/concepts/states | 2026-05-13 10:33 CST | 高 |
| 官方文档 | Dagster Run Retries | https://docs.dagster.io/deployment/execution/run-retries | 2026-05-13 10:33 CST | 高 |
| 官方文档 | Airflow DAGs | https://airflow.apache.org/docs/apache-airflow/stable/core-concepts/dags.html | 2026-05-13 10:33 CST | 高 |
| 官方文档 | Airflow Scheduler | https://airflow.apache.org/docs/apache-airflow/stable/administration-and-deployment/scheduler.html | 2026-05-13 10:33 CST | 高 |
| 官方文档 | OpenAI Codex Non-interactive | https://developers.openai.com/codex/noninteractive | 2026-05-13 10:33 CST | 高 |
| 官方文档 | OpenAI Codex Sandboxing | https://developers.openai.com/codex/concepts/sandboxing | 2026-05-13 10:33 CST | 高 |
| 官方文档 | Claude Code Headless | https://code.claude.com/docs/en/headless | 2026-05-13 10:33 CST | 高 |
| 官方文档 | OpenHands SDK Getting Started | https://docs.openhands.dev/sdk/getting-started | 2026-05-13 10:33 CST | 高 |
| 官方文档 | OpenHands Docker Runtime | https://docs.openhands.dev/usage/runtimes/docker | 2026-05-13 10:33 CST | 高 |
| 官方文档 | SWE-agent Docs | https://swe-agent.com/latest/ | 2026-05-13 10:33 CST | 高 |
| 官方文档 | Aider Git Integration | https://aider.chat/docs/git.html | 2026-05-13 10:33 CST | 高 |
| 官方文档 | Git Worktree | https://git-scm.com/docs/git-worktree | 2026-05-13 10:33 CST | 高 |
| 官方文档 | GitHub Actions Schedule Events | https://docs.github.com/en/actions/reference/events-that-trigger-workflows#schedule | 2026-05-13 10:33 CST | 高 |
| 官方文档 | systemd.timer | https://www.freedesktop.org/software/systemd/man/latest/systemd.timer.html | 2026-05-13 10:33 CST | 高 |
| 官方文档 | Cloudflare Pages Direct Upload | https://developers.cloudflare.com/pages/get-started/direct-upload/ | 2026-05-13 10:33 CST | 高 |
| 官方文档 | Cloudflare Wrangler Pages Commands | https://developers.cloudflare.com/workers/wrangler/commands/pages/ | 2026-05-13 10:33 CST | 高 |
| 官方文档 | Cloudflare Workers Custom Domains | https://developers.cloudflare.com/workers/configuration/routing/custom-domains/ | 2026-05-13 10:33 CST | 高 |
5. 详细发现
5.1 当前失败根因:不是“夜里没跑”,而是缺少状态机和恢复协议
现有 `night_tick.py` 事实上承担了四种职责:队列状态机、AI worker 调度、验证提交、通知汇报。任何一个环节失败,脚本都没有 durable checkpoint、resume branch、artifact contract 和人工介入点,于是出现:
- stale `in_progress` 不阻塞后续 pending;
- false-positive failed 无自动分类;
- dev 阶段产物存在,但 review/validation/commit 缺闭环;
- 浏览器 E2E 完成却没有 reducer/commit;
- cron 自身显示 ok,但业务状态未成功推进。
这说明“cron job 成功”与“业务 workflow 成功”已经脱钩。平台必须把业务状态提升为一等对象。
5.2 Scheduler 层:cron/systemd/GitHub Actions 只能触发
`systemd.timer` 的职责是基于时间触发 unit;GitHub Actions schedule 也是 cron-style event;Airflow 则把 schedule、DAG run、task instance、dependency、retry 和 UI 分成独立概念。这给当前系统的启发是:
- Hermes Cron 可以继续作为触发器;
- 但每次触发只应调用 `start_or_resume_workflow(queue_id)`;
- 业务状态必须存储在 workflow engine / DB 中,而不是靠 JSON + lock 文件临时拼凑。
5.3 Durable workflow:Temporal 是长期主控首选
Temporal 的核心优势:
- Workflow Execution 有事件历史;
- Activity 有 retry policy、timeout、heartbeat、worker task queue;
- TypeScript SDK 可与现有 Bun/Node 生态靠近;
- 本地 dev server 自带 Web UI,可先在本机落地;
- query/signal 适合 human-in-loop:暂停、批准、重跑某步骤、标记任务失败。
但要注意 Temporal 的约束:Workflow 必须 deterministic。所有外部副作用都必须封装成 Activity:
- 创建/清理 git worktree;
- 调用 `codex exec` / `claude -p`;
- 读取 diff、生成 artifact;
- 跑测试、浏览器 E2E;
- git commit;
- 发 Weixin/Telegram 通知。
这正好逼迫平台形成清晰边界:Workflow 只做编排和状态转移,Activity 做外部世界。
5.4 BullMQ/Celery:适合快速落地队列,但需补平台层
BullMQ 提供 failed job retry、backoff、stalled job 和 FlowProducer parent-child flows;Celery 提供 task retry、states、acks、canvas chain/group/chord。它们证明“队列 + worker + retry”是成熟模式。
但夜间编程还需要:
- artifact schema;
- worktree lifecycle;
- reviewer gate;
- deterministic validation;
- reducer merge queue;
- secret/pollution scanning;
- commit policy;
- dashboard 和人工介入。
这些不是 BullMQ/Celery 自动提供的,需要平台自己实现。因此 BullMQ 最适合 Phase 1 原型或局部任务队列,不建议作为最终唯一真相来源,除非明确接受自建大量控制面。
5.5 LangGraph:适合 agent 内部状态,不适合取代外部工程治理
LangGraph 的 persistence/checkpointer 支持 checkpoint、thread_id、state history、time travel、pending writes、interrupt/human-in-loop。这非常适合 AI agent 的内部推理图和人工审批节点。
但本场景还涉及本地文件系统、git worktree、测试进程、端口、浏览器、提交和多仓库迁移。LangGraph 可作为单个 AI worker 的内部“脑内流程”,外层仍应由 Temporal/BullMQ 这类工程控制面负责资源与副作用。
5.6 Airflow / Dagster / Prefect:可借鉴,不宜作为首选内核
Airflow 提供 DAG、Task Instance、DAG Run、scheduler、UI、backfill 和 trigger rules;Dagster/Prefect 提供状态、retry、作业编排和观测。这些能力对“可观测批处理”很成熟。
不首选的原因:
- 它们的中心假设更接近数据/ETL/批处理,而不是“代码 diff 的生成、审查、合并和提交”;
- AI coding task 的不确定性需要更细粒度的 artifact/reducer/human gate;
- 本机单人公司场景下,Airflow 的部署和 DAG 管理成本偏高。
它们适合借鉴 UI 和状态模型,或在未来需要跨机器/跨数据作业时接入。
5.7 Worker 隔离:git worktree 是最低正确层,容器是第二层
当前同一工作树写入导致最大风险:diff 混杂、未提交产物污染后续任务、失败后不知道该 revert 还是继续。Git 官方 worktree 支持一个仓库多个 working tree;Aider 文档也强调自动 commit 和 dirty separation 的价值。
推荐隔离层级:
- **每个任务一个 git worktree**:路径如 `.night-platform/worktrees/{repo}/{task_id}`。
- **每个 worker 独立 run dir**:保存 prompt、stdout、stderr、exit code、diff、test report、browser evidence。
- **AI CLI sandbox 权限**:Codex 使用 workspace-write/read-only 分工;review worker read-only。
- **容器/namespace 可选增强**:对高风险任务使用 Docker/Firecracker/E2B/Slicer 类 microVM;本机先不必一开始上 K8s。
5.8 AI coding worker 对比
| Worker | 优势 | 风险 | 建议角色 |
|---|---|---|---|
| Codex CLI | 非交互、sandbox、适合自动化 | 需要严格权限和 artifact 合同 | 主开发 worker / reviewer worker |
| Claude Code headless | headless/CI 资料成熟,适合复杂实现 | 成本与上下文控制需管理 | 主力开发或重构 worker |
| OpenHands | Docker runtime、文件系统 mount、agent runtime | 挂载 rw workspace 有删除/污染风险 | 中期评估为封闭 worker runtime |
| SWE-agent | ACI 思想适合基准化代码修复 | 更偏 benchmark/research | 借鉴接口与评测方式 |
| Aider | git 集成、自动 commit、dirty separation | 自动提交策略需纳入平台审查 | 小任务/交互式辅助 |
| OpenCode | 开源、终端 agent、生态可控 | sandbox/headless 能力需进一步验证 | 备用 worker / 低成本 worker |
5.9 推荐目标架构
Trigger Layer
Hermes Cron / systemd.timer / manual CLI
|
v
Workflow Control Plane
Temporal namespace: night-coding
Workflow: NightQueueWorkflow(queue_id)
Child Workflow: TaskWorkflow(task_id, repo, branch, spec)
|
v
Activity Layer
prepare_worktree(task)
run_dev_agent(task, worktree, sandbox=workspace-write)
collect_artifacts(task)
run_review_agent(task, sandbox=read-only)
run_validation(task)
pollution_scan(task)
reducer_merge(task)
local_commit(task)
publish_report(task)
notify(task)
|
v
State / Artifact Store
SQLite/Postgres: task state, attempts, locks, metrics
Filesystem/R2: prompts, logs, diffs, screenshots, reports
Git: final accepted commits only
|
v
Human-in-loop
approve retry / mark failed / inspect diff / resume / abort
5.10 状态机草案
queued
-> preparing_worktree
-> dev_running
-> dev_artifacts_ready
-> review_running
-> review_passed | review_failed
-> validation_running
-> validation_passed | validation_failed
-> reducer_pending
-> committed
-> reported
-> done
任何状态 -> blocked_manual
任何可重试失败 -> retry_scheduled
任何不可恢复失败 -> failed_terminal
关键不变量:
- 发现任何 active/stale `in_progress`,不得越过它消费新 pending。
- 所有 task attempt 都有 attempt_id,不覆盖历史。
- worker 输出必须落盘为 artifact,而不是只写聊天总结。
- validation 不通过不得 commit。
- commit 必须仅包含当前 task 的 reducer diff。
- push 永远需要人工确认。
6. 边界条件
- **平台范围**:本机 NixOS,主要项目在 `/home/biem/code/DeepKr` 与 `/home/biem/code/biem-site`。
- **仓库范围**:Admin/Web/Server 多仓库;每个任务应指定 repo、base branch、worktree path。
- **AI CLI 范围**:Codex/Claude Code/OpenCode/Aider/OpenHands 可作为 worker;不能把任何 AI CLI 当 durable engine。
- **依赖安装**:不得自动安装;验证阶段优先复用已有 `node_modules` 或使用显式人工批准。
- **安全范围**:不输出 token/API key;pollution scan 应识别 secret 内容,而非粗暴拦截 `.env.example`。
- **网络范围**:大陆网络条件是常态风险;下载/部署/包安装需区分 direct/proxy/mirror。
7. 建议与行动项
Phase 0:止血(0.5-1 天)
- 保持 Hermes Cron paused。
- 修 `night_tick.py` 最小状态机:已有 `in_progress` 时进入 resume/review/manual,不得取新 pending。
- 修 pollution scan:允许 `.env.example` / `.env.template`;扫描内容是否含真实 secret。
- 处理 `admin-01-shell-navigation`:复核 dev artifact,跑 validation,能完成则 commit,否则标记 failed_terminal。
- 处理 Web Browser E2E 脏工作树:reducer + validation + local commit 或回滚。
Phase 1:平台原型(2-4 天)
- 建 `night-platform` 小仓库或 DeepKr 子目录。
- 实现统一 task schema:`task_id/repo/base_branch/spec/constraints/validation/commit_policy`。
- 每任务创建 git worktree。
- 用 BullMQ 或 SQLite queue 快速跑通一条任务。
- 产物包括:prompt、dev log、review log、diff、test output、screenshots、final report。
Phase 2:Temporal 化(3-7 天)
- 引入 Temporal dev server + TS SDK。
- 把每个步骤封装为 Activity。
- 实现 query/signal:pause/resume/approve_retry/mark_failed/abort。
- 接 Temporal Web UI 与本地 HTML dashboard。
- 对同一 `admin-01` 做故障注入:杀 worker、断通知、测试失败、stale lock,验证可恢复。
Phase 3:夜间规模化(1-2 周)
- 迁移 Admin 队列剩余任务。
- 增加 reviewer agent 与 deterministic validation gates。
- 引入 cost/turns/failure-rate/mean-time-to-recovery 指标。
- 将每晚最终报告发布到本地 dashboard 和消息渠道。
- 仍然 no push;push 作为人工白天动作。
Phase 4:重型增强(按需)
- 容器隔离或 microVM worker。
- Cloudflare/R2 存 artifact;网页 dashboard 公开只放 redacted 报告。
- 多仓库 merge train。
- 失败案例自动沉淀 skill / regression test。
8. 未解决问题
- Temporal 是否进入 `/etc/nixos` 的 OS/User/Dev 哪一层,需要结合 NixOS-AIOS 3x3 模型再定。
- 本机是否已有可复用 Redis/Postgres,需要后续做系统资源盘点。
- Browser E2E 的 evidence schema 尚未统一:截图、trace、console、HAR 应如何归档。
- Codex/Claude/OpenCode 的成本、并发、5 小时窗口和模型路由,需要平台接入实际计量。
- Cloudflare dashboard 是否只发布最终报告,还是也发布实时夜间状态,需要单独做安全边界设计。
9. 置信度评估
- **总体置信度:高。** 关键结论均由官方文档或本地实测状态支持。
- **Temporal 作为长期主控:中高。** durable execution 证据强;不确定性在于本机部署与维护成本。
- **BullMQ 作为 Phase 1:中高。** 技术适配性强;不确定性在于是否会演变为自造半个 Temporal。
- **git worktree 隔离:高。** 直接对应当前同工作树污染问题。
- **Airflow/Dagster/Prefect 不首选:中。** 判断基于问题域适配度;若未来接入更多数据作业,结论可调整。
附录 A:当前 Admin 队列状态快照
admin-00-foundation completed
admin-01-shell-navigation in_progress ← stale,无进程
admin-02-api-auth-openapi failed ← .env.example false-positive
admin-03-capability-governance-ui pending
admin-04-server-admin-overview-api pending
admin-05-dashboard-ui-live pending
admin-06-server-user-management-api pending
admin-07-user-management-ui pending
admin-08-server-operations-api pending
admin-09-operations-ui pending
admin-10-provider-audit-settings pending
admin-11-remove-admin-from-customer-web pending
admin-12-browser-e2e-live pending
admin-13-hardening-docs-ci pending
附录 B:一条任务的 artifact contract 草案
{
"task_id": "admin-01-shell-navigation",
"attempt_id": "20260513T010000Z-01",
"repo": "AI_Growth_Factory_Admin",
"base_branch": "develop",
"worktree": ".night-platform/worktrees/admin-01",
"worker": { "type": "codex", "model": "gpt-5.5", "sandbox": "workspace-write" },
"inputs": ["spec.md", "prompt.md"],
"outputs": ["dev.log", "review.log", "diff.patch", "validation.json"],
"validation": {
"typecheck": "passed",
"unit": "passed",
"browser_evidence": "optional"
},
"decision": "commit | retry | blocked_manual | failed_terminal",
"commit": { "hash": null, "message": null }
}