Archon 维护者每日晨会工作流 maintainer-standup:基于方向文档的 PR 分级三审与进度对账
【免费下载链接】ArchonThe first open-source harness builder for AI coding. Make AI coding deterministic and repeatable.项目地址: https://gitcode.com/GitHub_Trending/archon3/Archon
导读
maintainer-standup是 Archon 仓库内置的一套维护者晨会工作流:每天自动拉取最新dev分支、抓取全部开放 PR 与指派给你的 issue,对照项目方向文档 direction.md 将其分类为 P1–P4,并与上一次运行的状态做对比,输出"自上次以来解决了什么、你交付了什么、哪些积压项还在老化"。读完本文,你将掌握如何为一名新维护者初始化该工作流、它背后的三层引擎实现(并行采集脚本 → LLM 合成 → 持久化),以及如何通过修改命令模板与 YAML 定义来定制简报格式。
一、这个工作流解决什么问题
开源项目维护者的早晨通常是一连串没有上下文的请求:新 PR、新 issue、待评审的 review request、自己上次提交的遗留任务。maintainer-standup把这些散乱信号聚合成一屏可读完的优先级简报,并做到两件事:
- 按项目方向分类:所有开放 PR 依据 direction.md 中的 "What Archon IS / IS NOT" 被分为 P1–P4,其中 P4 是"与方向冲突、应礼貌拒绝"的候选,且每一条都必须引用具体条款(如
direction.md §single-tenant-per-install)。 - 跨运行进度对账:通过读取上一次写入的 state.json(gitignored),对比本次抓取的快照,自动识别"上次观察到的 PR/issue 现在已关闭/合并""你最近提交了什么""哪些 carry-over 项已老化"。
从源码结构看,这是一套"确定性采集 + LLM 合成 + 确定性持久化"的模板:采集与落盘阶段不依赖 AI 判断,只有合成阶段使用模型,这与 Archon 作为"governed agentic automation engine"的设计方向一致。
二、目录结构与文件职责
工作流运行于.archon/maintainer-standup/,其中文件分为**已提交(committed)与本地个人(gitignored)**两类:
| 文件 | 是否提交 | 用途 |
|---|---|---|
| direction.md | ✓ | 项目北极星文档——Archon 是什么/不是什么。全体维护者共享,驱动 PR 分类与礼貌拒绝判定 |
| README.md | ✓ | 本文档 |
| profile.md.example | ✓ | 新维护者复制用的个人配置模板 |
profile.md | gitignored | 个人配置(gh handle、角色、关注领域) |
state.json | gitignored | 自动写入的跨运行 carry-over 状态 |
briefs/YYYY-MM-DD.md | gitignored | 每日文本简报,最近 3 篇会读入下一次运行 |
设计取舍:direction.md必须提交,因为分类决策要在不同维护者、不同运行之间保持一致;而profile.md、state.json、briefs/是个人化的(你的关注点、你的日常笔记、你的阅读材料),因此由每个维护者自行管理、不进入版本库。
工作流的三个脚本与合成命令则位于:
- .archon/scripts/maintainer-standup-git-status.ts — git 状态采集
- .archon/scripts/maintainer-standup-gh-data.ts — GitHub 数据采集
- .archon/scripts/maintainer-standup-read-context.ts — 本地上下文读取
- .archon/scripts/maintainer-standup-persist.ts — 结果持久化
- .archon/commands/maintainer-standup.md — 合成节点的提示词(brief 格式定义处)
- .archon/workflows/maintainer/maintainer-standup.yaml — 工作流 DAG 定义
三、新维护者初始化:三步上手
1. 复制个人配置模板
cp .archon/maintainer-standup/profile.md.example .archon/maintainer-standup/profile.md2. 编辑 profile.md
模板采用 YAML frontmatter + Markdown 正文的结构(见 profile.md.example):
--- # Required: your GitHub login (used by gh queries for review-requested / assigned filters). gh_handle: your-github-login # Suggested: drives how broadly the synthesizer classifies the queue. # - main_maintainer / everything → triage all open PRs, not just yours # - reviewer / focus-area → narrower coverage role: main_maintainer scope: everything ---关键点:
gh_handle是必需项,会被maintainer-standup-gh-data.ts用正则^gh_handle:\s*(\S+)\s*$从 frontmatter 中解析,用于 review-requested、assigned、authored-by-me 等过滤查询;缺失时脚本只输出一条 stderr 警告,相关数据字段会为空数组。role/scope决定合成器扫描队列的广度:main_maintainer+everything表示全量 PR 分类;子维护者可用更窄的范围。- 正文中的Currently focused on是可选但推荐的:合成器会对列出的关注项在同一 P 级内加权排序。
- 正文是一段"你想要简报如何调校"的自由文本,合成器会逐字读取——直接写你真实想要的过滤规则,例如示例中的:"我是聚焦 workflow engine 的子维护者,优先展示触及
packages/workflows/的 PR;非 P1 的 adapter-only PR 降权。"
3. 运行工作流
archon workflow run maintainer-standup ""首次运行是基线(prior_state为 null 且无历史 briefs),不做对比、直接输出分类与状态快照;后续运行才会对照 state.json 输出 "Resolved since last run" / "What you shipped" / 老化的 carry-over 项。
四、引擎视角:三层流水线如何工作
工作流定义见 maintainer-standup.yaml,共 5 个节点,分三层:
第一层:三个并行采集脚本(纯 bun,无 AI)
| 节点 | 脚本 | 超时 | 采集内容 |
|---|---|---|---|
git-status | maintainer-standup-git-status.ts | 60s | git fetch origin dev,安全时 fast-forward 本地 dev,抓取自上次记录 SHA 以来的新提交 + diff stat |
gh-data | maintainer-standup-gh-data.ts | 180s | 全部开放 PR(完整元数据)、review-requested PR、authored-by-me PR、指派给你的 issue、近 7 天新开的无标签 issue、自上次运行以来关闭/合并的 PR 与 issue |
read-context | maintainer-standup-read-context.ts | 10s | 读取direction.md、profile.md、state.json与最近 3 篇 briefs |
git-status 的细节(源码):
- 所有 git 调用使用
execFileSync+ argv 数组(不经过 shell),规避元字符注入风险; pull_status有五种取值:pulled/fetch_only/pull_failed/not_on_dev/dirty——不在 dev 分支、或工作区有未提交改动时不会强行 pull,只 fetch 并把状态如实上报,交给合成器在简报中提示;- 输出 JSON 形如
{ current_dev_sha, prior_dev_sha, current_branch, is_dirty, pull_status, new_commits, diff_stat }。
gh-data 的细节(源码):
- 开放 PR 拉取上限
PR_LIMIT = 1000,若触顶会输出显式警告——因为下一轮"resolved since last run"的差异检测要求observed_prs必须完整覆盖all_open_prs; - 通过 GitHub REST 的
/issues/comments?since=...与/pulls/comments?since=...两个端点抓取自上次运行以来的贡献者回复,过滤掉维护者本人与[bot]账号,按 PR/issue 号分组,kind 分为issue/pr_conversation/pr_review(同一 PR 上两种都出现时升级为pr_review,即行内评审,通常最需要代码级回应); - 额外输出
my_recent_commits(维护者自己最近提交到 origin/dev 的 commit 列表)与since_date(上次last_run_at或 7 天兜底)。
read-context 的细节(源码):
- 预计算"今天日期 + 3 天后的 deadline"并直接输出
YYYY-MM-DD,理由是 LLM 做日历运算不可靠,且不能锚定过期的last_run_at; - 读取
reviewed-prs.json作为跨工作流记忆:这是maintainer-review-pr工作流写入的{ PR号: { reviewed_at, gate_verdict, run_id } }映射,晨会合成器据此在每条 PR 旁标注✓ reviewed Nd ago,并在贡献者于评审后又 push 时提示"需要重跑评审"。
第二层:合成节点(Claude Sonnet,结构化输出)
synthesize节点depends_on上述三个脚本,使用命令 maintainer-standup.md。其输出是恰好两部分:
- 简报 Markdown:以字面行
# Maintainer Standup — YYYY-MM-DD开头,随后是分类简报; - 状态 JSON 块:以
ARCHON_STATE_JSON_BEGIN/ARCHON_STATE_JSON_END两个独立行包裹的合法 JSON。
硬性规则包括:不允许前置散文、不允许把整个响应包成{"brief_markdown": ..., "next_state": ...}JSON 对象(那是旧契约)、分隔标记不允许被 markdown 代码围栏包裹、关闭标记之后不允许有任何内容。
合成器内部按阶段工作:
- Phase 1 加载输入:解析三个上游节点的 JSON;
- Phase 2 分析:
- 检测首跑 vs 持续运行;
- 对比
prior_state检测进度(resolved / carry-over 复查 / what you shipped / new since last run); - 读取 direction 与 profile 驱动分类范围;
- 全量 PR 分类 P1–P4:P1 为可合并待评审(
reviewDecision与mergeStateStatus判定)、安全修复、破坏 dev 或阻塞发版的问题;P2 为本周内需处理;P3 为低优先级;P4 必须引用direction.md §clause; - 用
gh pr view / diff / checks选择性深入 5–10 个最模糊的 PR(60+ 全钻取是浪费); - 对 carry-over 按
first_seen老化升级;结合reviewed_prs标注评审历史与"贡献者已 push"的过期警告;
- Phase 3 生成输出:简报 + 状态块,状态块中
carry_over保留原始first_seen、observed_prs必须包含全部开放 PR(防止静默丢失)。
第三层:持久化节点
persist节点通过 bash 管道将合成输出喂给maintainer-standup-persist.ts(源码)。之所以用 bash 节点而非 bun 节点,工作流 YAML 的注释说明得很清楚:合成输出是含 markdown 代码围栏与散文的原始文本,若替换进 bun 脚本体不是合法的 JS 表达式,而 bash 节点由框架负责 shell 引用。
持久化脚本做两件关键事:
- 双格式容错:首选
ARCHON_STATE_JSON_BEGIN/END分隔符格式(取最后一个完整的 BEGIN/END 对,简报取第一个 BEGIN 之前的所有内容);若解析失败,回退到 JSON-wrapper 格式({"brief_markdown": ..., "next_state": ...})——注释明确说明这是因为 Pi/Minimax 会无视分隔符指令、稳定输出 JSON-wrapper。两者都失败时打印原始输出到 stderr 供恢复并exit(1)。 - 落盘:把简报写到
briefs/<YYYY-MM-DD>.md(从第一个#标题起截断前置散文),把状态 JSON 写到state.json(2 空格缩进 + 换行)。
五、在真实 checkout 中运行:为什么拒绝 worktree 隔离
该工作流必须在实时 checkout中运行:它要读取.archon/maintainer-standup/本目录、要git pull origin dev。因此 YAML 中显式声明:
worktree: enabled: false # Live checkout — needs to git pull and read .archon/maintainer-standup/对应地,CLI 层面的--branch与--no-worktree参数都会被拒绝。从 packages/cli/src/commands/workflow.ts 的校验逻辑可以印证这一约束的实现:
--branch与--no-worktree互斥("--branchcreates an isolated worktree (safe).--no-worktreeruns directly in your repo (no isolation).");- 当工作流策略声明
worktree.enabled: false时,显式传--branch会被判定冲突("--branchrequires an isolated worktree... Drop--branchor change the workflow'sworktree.enabled"); - 显式传
--no-worktree与禁用 worktree 的策略不矛盾,会静默接受(--no-worktree is redundant but not contradictory — silently accept)。
也就是说:正常情况下直接运行archon workflow run maintainer-standup ""即可,CLI 会尊重 YAML 中的worktree.enabled: false策略在实时目录执行;只有显式传--branch这类与策略冲突的旗标才会被拒。
六、维护 direction.md:让分类决策可复现
direction.md 是 PR 分类期间"Archon 是什么/不是什么"的唯一事实来源。维护它的三条纪律:
- 分类需要理由时,就添加条款:当一次分类决策需要正当性说明(好让下一位维护者得出相同结论)时,往 IS / IS NOT 清单里加一行。
- 拒绝 PR 时引用条款:例如拒绝多租户类 PR 时写
direction.md §single-tenant-per-install,拒绝代理基础设施类 PR 时写direction.md §deployment-recipes。文档本身还维护了若干"triage clause"小节(如 §isolation-never-inferred、§when-grammar、§prompt-computation),供 PR 评论中直接引用。 - 保持条目简短:每条一两行,目的是分类时快速查阅,而不是写宣言。尚未定论的决策放进 "Open questions" 小节,触及这些领域的 PR 应显式提出该问题等待决策,而不是被静默接受或拒绝。
合成器还会输出Direction questions raised:那些触及direction.md尚无立场的领域、但 PR 本身又提出了问题的场景,会被汇入状态 JSON 的direction_questions字段,供维护者把决策有意识地吸收进方向文档,而不是逐案临时拍板。
七、定制简报格式
输出结构由两个文件共同决定:
- 模板与段落:
.archon/commands/maintainer-standup.md的 Phase 3 模板(## Since last run、## What you shipped、## Replies waiting on you、## P1 — Do today…## P4 — Polite-decline candidates、## Carry-over still pending等章节)。想改章节或换一套 P 级方案,改这里。 - 结构化输出 schema:
.archon/workflows/maintainer/maintainer-standup.yaml中的节点拓扑与output_format相关约束。想调整状态 JSON 的字段,需要同步改合成命令与persist脚本的解析逻辑。
命令模板还内建了 PHASE_3_CHECKPOINT 自查清单,其中几条值得注意的约束:响应必须以# Maintainer Standup标题开头(无前置散文)、状态块必须合法 JSON(无尾随逗号、字段齐全)、每个开放 PR 要么进 P1–P4 要么进observed_prs(不允许静默丢弃)、P4 条目必须引用具体direction.md条款、carry-over 未决项保留原始first_seen、state.last_dev_sha必须取自git-status.output.current_dev_sha。
八、延伸到其他维护场景
maintainer-standup不是孤立的工作流,它和仓库中的其他维护设施协同:
- repo-triage(.archon/workflows/maintainer/repo-triage.yaml):全仓库级的分诊自动化,与晨会互补——晨会面向"今天该做什么",repo-triage 面向批量自动分类;
- maintainer-review-pr(.archon/workflows/maintainer/maintainer-review-pr.yaml):其
record-review节点写入reviewed-prs.json,晨会读取它标注评审历史——这是仓库内两个工作流通过共享文件实现跨运行记忆的实例,无需数据库; - 方向文档的更新流程:direction.md 自身规定了演进方式——分类迫使方向决策时新增 IS/IS NOT 行、决策后把 "Open questions" 条目移到 IS/IS NOT、PR 评论中引用具体条款。
在 Archon 的工作流语言里,这套模式是"确定性脚本采集事实 + LLM 只做判断 + 确定性落盘"的标准组合,maintainer-standup正是这一组合在维护者运营场景上的完整示范:要复刻同类日报(比如社区周报、发布前 checklist 日报),只需要替换三个采集脚本的查询与合成命令的模板。
【免费下载链接】ArchonThe first open-source harness builder for AI coding. Make AI coding deterministic and repeatable.项目地址: https://gitcode.com/GitHub_Trending/archon3/Archon
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考