Hermes WebUI 的 Sprint 工程方法论:从活跃队列到发布闸门(SPRINTS.md 深度解读)
【免费下载链接】hermes-webuiHermes WebUI: The best way to use Hermes Agent from the web or from your phone!项目地址: https://gitcode.com/GitHub_Trending/he/hermes-webui
本文基于 Hermes WebUI 仓库中的 SPRINTS.md 展开,系统讲解该项目“主题式 Sprint(sprint)”的规划与交付机制:Sprint 的五大组成要素、活跃候选队列的筛选方式、五条规划原则与强制发布闸门(pre-release gate)、3–7 天的 Sprint 时间线,以及可直接复制的 Sprint 计划模板。读完本文,你将掌握一个高频发布(单日多次 ship)的开源项目是如何用文档化的流程来保证“批量交付的连贯性”与“单 PR 快速修复”并存的,并能把这套方法论套用到自己的项目中。
1. Sprint 的定义:主题式批处理,而非日历迭代
SPRINTS.md 开篇即给出当前状态快照:
Current state: v0.51.792 | ~11,500 tests | port 8787 Target A (CLI parity): ✅ Complete Target B (Claude parity): ~95% — full subagent transparency UI and code-execution cells remain
其中“~11,500 tests”并非手写的静态数字,TESTING.md 说明了它的来源:自动化测试通过./scripts/test.sh tests/ --collect-only -q现场收集统计,且每个 PR 会在 GitHub Actions 上跑 Python 3.11 / 3.12 / 3.13(各 3 个并行 shard)、ruff lint 门禁、headless 浏览器冒烟和 Docker 冒烟。pytest tests/ --collect-only -q也能在本地验证该数字。而 scripts/test.sh 中对解释器版本的支持区间硬编码为(3, 11) <= sys.version_info[:2] <= (3, 13),与 SPRINTS.md 中“CI green on Python 3.11 / 3.12 / 3.13”的发布闸门完全一致——这是文档承诺与测试脚本互相印证的一个典型例子。
在该仓库中,一个 Sprint 的定义是:一个主题批次(thematic batch),通常由 3–8 个 PR 作为一次 release 一起落地。每个 Sprint 必须包含五个固定要素:
- Theme(主题)——一句话框定“这次改什么”;
- Items(条目)——选中的工作项,每条带跟踪 issue / PR 编号;
- Out of scope(范围外)——明确推迟了什么、为什么推迟;
- Risks(风险)——已知的“锋利边缘”(sharp edges);
- Retro(回顾)——发布完成后总结学到了什么。
一个关键的分流规则:不符合任何计划 Sprint 的外部贡献者 PR,会以 patch 版本(v0.50.X)单独发布;Sprint 只留给“条目之间互相强化”的连贯批次。这与 ROADMAP.md 中声明的版本约定互相咬合:
- Patch(
v0.51.X)——小批次、贡献者 PR 发布、hotfix; - Minor(
v0.X.0)——Sprint 完成、新特性面、架构里程碑; - Major(
v1.0.0)——特性面稳定且各客户端可靠性达到稳态时才宣布。
CHANGELOG.md 是这套约定的落地证据:Unreleased 区里每条修复都带有 issue/PR 编号(如#7525、#7339),单 PR 级修复以 patch 形式连续堆积,而不必等待 Sprint 批次——这正是“per-PR release velocity”原则的直接体现。
2. 活跃 Sprint 候选队列(Active sprint candidates)
SPRINTS.md 维护了一张“活跃队列”:所有当前打了sprint-candidate标签、且根因已确认或设计方向已定的 issue。文档强调“队列保持小规模——它就是接下来 1–2 个 Sprint 的工作量”,更大的特性需求池放在 ROADMAP.md 的 Forward Work 章节。当前的候选表为:
| # | Title | Type | Sprint fit |
|---|---|---|---|
| #1458 | Persistent-host crashes — bootstrap fork pattern, state.db FD leak, HTTP-unhealthy wedge | bug, stability | Stability sprint candidate |
| #1426 | OpenRouter free-tier:freevariants invisible (tool-support filter) | bug + feat | Model picker sprint candidate |
| #1362 | In-app OAuth login for Codex and Claude (currently terminal-only) | feat, ux | Onboarding sprint candidate |
| #1360 | macOS desktop app — auto-scroll overrides user scroll (#677 regression) | bug, ux | Desktop app polish |
| #1291 | GLM mutually exclusive between main agent and auxiliary title generation | bug | Auxiliary-route sprint |
这张表本身就说明了筛选逻辑:每个候选项都已带有“Sprint fit”判定,即它天然属于哪个主题 Sprint(稳定性、模型选择器、onboarding……)。从仓库测试命名可以侧面印证这些候选的真实存在感:test_issue1458_stability_hardening.py、test_issue1426_openrouter_free_tier_live_fetch.py、test_issue1362_codex_oauth_onboarding.py等测试文件按 issue 编号命名(tests 目录中大量test_issueXXXX_*.py文件即为 issue 锚定的回归测试),与 SPRINTS.md“每个条目带跟踪 issue”的要求一致。
3. 五条规划原则
这是 SPRINTS.md 的核心方法论部分,五条原则各自解决一类实际工程问题:
3.1 Phase-0 fit assessment(收益-成本预筛)
每个 Sprint 候选先过一道边际收益筛查:这是让真实用户可感知地变好,还是增加维护成本高于收益的表面积?用五问筛查:need(需要吗)/ shape(形态对吗)/ bloat(是否臃肿)/ clutter(是否杂乱)/ scope(范围可控吗)。
3.2 Salvage over absorb(抢救优先于整体吸收)
当贡献者 PR 是半成品或范围错位时,优先做法是把其中的好部分“裁剪”进维护者侧 PR,并用Co-authored-by署名,而不是要求对方反复 rebase;只有当 PR 确实可以原样交付时才整体吸收。这避免了贡献体验中常见的“多轮 rebase 拉锯”。
3.3 Independent-review gate(独立评审闸门)
自建 PR 必须满足二选一:(a) 在合并前 stage diff 上跑一遍 Opus advisor pass;或 (b) 由独立评审人评审。高风险批次(大 LOC、安全、锁、持久性)两者都要。这与 ROADMAP.md 中“Autonomous project maintenance”一节呼应——该项目的 triage/评审/发布流水线由自治 agent 系统驱动(其通用化框架为 StewardOS),因此“独立评审”是流程里的硬闸门而非惯例。
3.4 Per-PR release velocity(单 PR 发布速度)
如果一个 PR 修复了真实 bug 且评审干净,当天就作为独立 patch release 发布,而不是等 Sprint 批次。“无摩擦(friction-free)是目标——Sprint 批次为连贯性而存在,不是为了任意分组。”CHANGELOG.md 中大量带单个 issue 编号的条目(如“Thanks @zicochaos. (#7339)”)就是这一原则的痕迹。
3.5 No feature creep mid-PR(PR 中途禁止范围蔓延)
贡献者在评审中提出范围扩展时,另开一个 PR 并从原 PR 链接过去;当前 PR 保持原边界。
4. 强制发布闸门(Pre-release gate, mandatory)
SPRINTS.md 规定每次发布必须完整跑完五步:
pytest tests/ -q --timeout=120全绿;- 浏览器 sanity check(对测试服务器做 HTTP 级 API 测试);
- 在合并前 stage diff 上跑 Opus advisor pass,并附书面 brief;
- 同步更新 CHANGELOG.md + ROADMAP.md + TESTING.md 的版本戳;
- CI 在 Python 3.11 / 3.12 / 3.13 上全绿。
跳过任何一步都需要维护者留下书面 “I'm doing an override” 说明。
其中第 2 步在仓库中有明确的自动化对应物:tests/browser_smoke.py 会启动真实的server.py(无 agent、临时端口、隔离的临时 state dir),在 headless Chromium 中加载关键页面,只要有任何 console error 或未捕获 JS 异常即失败;该测试刻意做到“无需凭证”(启动前剥掉所有*_API_KEY环境变量)。第 1 步则统一由 scripts/test.sh 封装执行(./scripts/test.sh),该脚本负责解释器解析(优先.venv)、Python 版本校验(3.11–3.13)与 pytest 透传。第 4 步的“版本戳同步”也解释了为什么 SPRINTS.md 头部会写死v0.51.792这样的状态行——它是发布闸门维护的活文档,而非一次性快照。
5. Sprint 时间线(Sprint shape):3–7 天六阶段
一个典型 Sprint 从启动到收尾运行 3–7 天,六阶段排期如下:
| Phase | Duration | Output |
|---|---|---|
| Triage | 0.5 day | Active queue → 选中条目 + 范围笔记 |
| Design / spike | 0.5–1 day | 需要设计的条目产出设计笔记;推迟项被记录在案 |
| Build | 2–4 days | 每个条目独立分支 + PR,便于独立评审 |
| Review | 0.5–1 day | 维护者 + Opus advisor 双通道评审;SHOULD-FIX 在发布内消化 |
| Stage + ship | 0.5 day | Stage 分支、完整测试套件、发布 PR、打 tag、部署、线上验证 |
| Hygiene | 0.5 day | 关闭 PR / issue、GitHub release notes、文档同步、Retro |
两条压缩规则值得注意:
- 小 Sprint(1–2 个 PR)压缩到 1–2 天全流程;
- 单 PR 发布跳过 stage 分支,直接从贡献者分支(或 fork 无写权限时维护者 rebase 的副本)经 release PR 发布。
这套弹性设计保证了“批次有批次、hotfix 有 hotfix”,与第 3.4 条“per-PR release velocity”原则形成闭环。
6. Sprint 历史与“不做什么”
6.1 代表性 Sprint
SPRINTS.md 挑出六个里程碑 Sprint 高亮(逐版本细节在 CHANGELOG.md,完整时间线在 ROADMAP.md 的 Sprint history 章节):
- Sprint 19— 认证 + 安全加固:第一个让应用可以安全地留在 localhost 之外运行的 Sprint;
- Sprint 21— 移动响应式 + Docker:双容器 compose 支撑了第一波自托管部署(对应仓库根目录的 docker-compose.two-container.yml 与 docker-compose.three-container.yml);
- Sprint 22— 多 profile 支持:CLI 对齐的关键解锁,profile 切换不再需要重启服务器;
- Sprint 25— macOS 桌面应用:原生 Swift + WKWebView 壳、Intel + Apple Silicon 通用 DMG、Sparkle 2 自动更新(独立仓库
hermes-webui/hermes-swift-mac); - Sprint 26— 可插拔主题:CSS 变量驱动的 8 主题系统,社区贡献者可以纯 CSS 加主题;
- Sprint 34— v0.50.0 UI 大改版:Composer 中心化控制、Control Center 模态、workspace 状态机、rAF 流式节流。
ROADMAP.md 的 Sprint history 表把 40+ 个 Sprint 压成了主题时间线(Sprints 1–6 奠基、7 Wave 2、19 安全、25 Mac 桌面、34 v0.50.0……),两者分工清晰:CHANGELOG 存逐版本细节,ROADMAP 存主题时间线,SPRINTS.md 只存“向前看”的规划。
6.2 全局 Out of scope(所有 Sprint 共同不做)
SPRINTS.md 专门列出一批“有意不放进路线图”的项,并注明理由以“省规划周期”:
- 多用户协作——代码库通篇假设单用户,重构等于从零改架构;
- 分享 / 公开会话 URL——需要带访问控制的托管后端 + CDN,超出自托管定位;
- 插件市场——Hermes skills 已覆盖该能力面;
- Anthropic / Claude 专有功能——Projects AI memory、Claude artifacts 同步,不可复现;
- Linux / Windows 原生壳——macOS 已完成,其他平台需求未确立,Web UI 本身在任意浏览器可用;
- App Store 分发——沙箱会破坏本地服务器模型;
- Python Web 应用的自动更新——Mac 应用由 Sparkle 2 覆盖;Web 应用走
git pull+ 重启,与其他 Python 服务无异。
这份“不做清单”与 ROADMAP.md Forward Work 中的 “Intentionally not planned” 章节相互印证(如“沙箱破坏本地服务器模型”“单用户假设贯穿全代码库”),说明它是跨文档一致的产品边界声明,而非某次规划的随口一提。
7. 可复制的 Sprint 计划模板
SPRINTS.md 最后附上了开新 Sprint 时直接复制的结构(原文完整保留):
# Sprint NN — <theme> **Version target:** vX.Y.Z **Theme:** <single sentence> **Date started:** YYYY-MM-DD **Status:** PLANNED | IN PROGRESS | COMPLETED — vX.Y.Z ## Items | # | Issue | Title | Complexity | Files | PR | |---|-------|-------|------------|-------|-----| ## Rationale Why these items, why now. ## Build approach Per-item branch + PR; or single combined branch if items are tightly coupled. ## Out of scope What did NOT make this sprint and why. ## Known risks Sharp edges to watch during review. ## PR Status | Issue | PR | Status | |-------|-----|--------| ## Retro (post-ship) What worked, what we'd do differently.模板本身即第 1 节“五要素”的展开:Items 对应 Items、Rationale/Out of scope/Known risks 对应范围与风险、PR Status + Retro 对应交付与回顾。文档同时声明:维护者每个 Sprint 的私人规划笔记存放在私有 workspace 仓库,SPRINTS.md 是对外公开的规划形态(public-facing planning shape)——这也是它刻意保持简洁、只放公开可验证信息的原因。
8. 小结:一份规划文档如何在仓库里“活”起来
把 SPRINTS.md 放回仓库语境看,它不是一份静态说明,而是被多处机制咬合的活流程:
- 向上:ROADMAP.md 提供主题时间线、Forward Work 需求池与版本约定,SPRINTS.md 的活跃队列从中取料;
- 向下:CHANGELOG.md 记录每个 Sprint/patch 的落地细节,TESTING.md 与 scripts/test.sh、
tests/下的 ~11,500 个测试构成发布闸门的可执行部分; - 横向:per-PR 快速发布与 Sprint 批次共存,用 patch/minor 版本语义区分,避免了“为了批次而拖延修复”的常见反模式。
这套机制的可借鉴点在于:Sprint 的最小单元不是时间(两周迭代)而是主题连贯的 PR 批次;每个候选项进队列前必须已有确认的根因或设计方向;发布闸门五步全部可执行(pytest、浏览器 sanity、独立评审、三文档版本戳、CI 三版本矩阵),且跳过必须留痕。对任何希望在高发布频率下保持交付连贯性的 Python + 原生 JS(无构建步骤)项目,SPRINTS.md + ROADMAP.md + CHANGELOG.md 三件套的组合方式都值得直接参考。
【免费下载链接】hermes-webuiHermes WebUI: The best way to use Hermes Agent from the web or from your phone!项目地址: https://gitcode.com/GitHub_Trending/he/hermes-webui
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考