研发协作
当开源项目 issue/PR 队列失控、维护者精力不足时…
为维护者团队设计一套按真实产能定制的 issue 与 PR 分诊系统:响应目标、标签体系、入口削减、安全报告通道、值班轮换、关闭与陈旧策略、自动化边界。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 49/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 85/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 60/100 ×0.15
适用场景
当开源项目 issue/PR 队列失控、通用
解决思路
- 先做访谈:一次问一个问题,尽量用多选题,跳过用户已答的。问题 1-6 是前置门槛(产能上限、截止日期、清库还是长期系统、队列规模、流入类型、项目性质与合同义务),没有它们就是在为想象中的项目做设计。若问题 1 答出实际为零小时,停止设计并直说:诚实的交付物是削减入口并发布“项目处于维护模式”声明,而不是没人会执行的标签体系。
- 根据问题 1、2、3 的答案重新排序所有后续菜单,并说明哪一项被提升或降级:硬截止日期提升本周能见效的动作(缩短承诺、chooser 路由、方向检查),降级季度后才见效的事;“明年仍要能用”提升增加 triager 和验证表单;产能极低则直接删除选项而非降级——没有加人权力的项目,add-triagers 不是杠杆,不得出现在交付物中。
- 第 1 步:改动前先测量队列。导出 tracker 数据并跑基线:`gh issue list --state all --limit 2000 --json number,title,state,createdAt,updatedAt,closedAt,labels,author,comments > issues.json`,再运行 `python3 scripts/triage-baseline.py issues.json --triage-prefix "kind/,priority/"` 和 `python3 scripts/triage-baseline.py issues.json --stale-days 120 --format json > baseline.json`。报告 open 数、年龄中位数/p90、未分诊占比、不活跃数、首次人工响应时间中位数与 p90、创建与关闭流量、标签使用情况(含只用一次的标签)。无可脚本环境时手工抽样 50 条估算同样指标。
- 把数字读回给用户再提任何建议:80% 是使用问题的队列与 80% 是无人应答 bug 报告的队列需要完全不同的干预。然后问逐条框架掩盖了什么:这些条目是否成簇?在大型陈旧积压中,按共同根因归入一个 tracking issue 并把其余重定向过去,往往比逐条分诊清得更多。在设计逐条机制之前先决定逐条还是聚类。
- 第 2 步:做产能算术。triagers × 每周场次 × 每场分钟 ÷ 每条分钟,与基线流入比较。不要引入“每条分钟”常数,用第 9 步试点实测的项目自身数字;在此之前三分钟只是本技能设定的规划占位值,不是行业实测值。深度调查不是分诊,它是分诊要排期的工作。
- 产能低于流入时,没有标签方案能解决。按“每维护者小时缓解的队列量”而非“打字最快”选三个杠杆:效率(削减入口 > 缩短承诺 > 增加 triager)、工作量(缩短承诺 > 削减入口 > 增加 triager)、价值(削减入口 > 增加 triager > 缩短承诺)、合规成本(削减入口 == 增加 triager > 在存在合同义务时缩短承诺,因为已发布目标在那里是承诺,缩短即合同变更)。效率会饿死“增加 triager”——唯一能提升产能、见效最慢的杠杆;只要项目预期一年后仍存在就应提升它。把所选杠杆写进交付物。
- 趁一切平静时现在就决定“容量闸门触发条件”:在什么流入率或有效报告占比下,项目将限制谁能开条目、限制每位作者的开放提交数、或改变吸引流量的激励。等到倦怠严重才采用闸门的项目都是危机即兴。
- 用产能数字而非雄心设定首次响应目标——是人工回复,不是修复,也不是机器人问候。
- 第 3 步:设计标签体系。按正交轴构建(type、state、priority、area、contributor-facing),每条最多每轴一个值。state 推动队列;priority 引发争论,保持项目能承受的最小规模。参考点:新仓库十个默认标签、最常安装的分诊技能中五个 state 角色加两个类别、Kubernetes 规模下六个前缀族;诚实答案通常介于前两者之间,只有所有权真正分裂时才接近第三个。
- 采用 PyTorch 分类法的两条规则(唯一有生产运行文档的):按置信度打标——高或中置信度才打标签,低置信度打“needs review”状态而非猜测;绝不让自动化打最高优先级——所有候选都转人工确认,priority 是下游后果最大、机器可判定性最低的轴。
- 在动 tracker 之前先提交标签体系供批准——强加给未同意维护者的体系一个月内就会腐化。
- 第 4 步:削减入口。按“每投入一小时设置所回收的分诊分钟”排序四种削减(无合规成本轴,四者都不对任何人产生义务):效率(chooser 路由 > 验证表单 > 禁用空白 issue > 自动打 type 标签)、工作量(禁用空白 issue == 自动 type 标签 > chooser 路由 > 验证表单)、价值(chooser 路由 > 验证表单 > 禁用空白 issue > 自动 type 标签)。
- 实施四项:1) chooser 路由——使用问题去论坛或聊天,商业请求去销售联系人;被路由的报告永不进 tracker,第 5-8 步不再触及。2) 用验证表单替换 markdown 模板,只要求真正改变结果的字段;每个被跳过的可选字段都在教报告者表单是装饰。3) 表单覆盖真实类别后禁用空白 issue。4) 从表单自动打 type 标签,tracker 有 issue type 时一并设置。效率会饿死选项 2(最高经常性价值、最多设置);bug 报告主导流入时把它提到第一位。没有地方路由使用问题的项目(问题 12)没有选项 1,本轮直接删除而非列为待办。
- 安全报告完全离开 tracker。每个成熟项目都运行同一三要素流水线:私有入口通道、有名且有规模上限的响应团队、协调披露的禁运机制。Apache 指示提交者绝不在公共 tracker 输入漏洞细节;没有安全邮件列表时,代码托管平台的私有漏洞报告是默认。
- 第 5 步:分配值班。无人拥有的流程不是流程。1) 明确谁分诊,轮换并写明班次长度(一周是常见单位)与指定备份;Mozilla 两级模型是最稳健的文档化模式:长期 triage owner 按组件负责,加每周轮换的 triage duty 做实际工作。2) 固定节奏与停止规则:一场在时间盒到点结束,而非收件箱清零,这样分诊能挺过尖峰。3) 设定场次顺序:最新未分诊优先(保护响应目标),然后是报告者已回复的条目,最后是固定积压配额。4) 授予 triage 级权限而非 commit 权限——多数 tracker 有可打标、关闭、指派而无写权限的角色,这是分诊团队超越提交者成长的方式。5) 定义升级:triager 可独自决定什么、什么等维护者、等待可多长。
- 决定定期分诊会议能否存活的三件事:为它构建的队列视图、异步预分诊(让会议是决策而非首次接触)、决策以标签或状态变更记录而非只写进会议纪要。Rust 编译器分诊会议是最清晰例子:Zulip 流预分诊,优先级通过替换标签设定,输出保持可查询。
- 第 6 步:给 PR 自己的闸门顺序。PR 有 issue 没有的硬性自动检查,不要复用 issue 流程。两个闸门不是菜单项,因为都是人工查看前触发的自动前置条件:sign-off(CLA 或 DCO)与外部作者 PR 的 CI 权限。没有 sign-off 不得合并,因为它记录的许可来源是项目对代码来源的唯一账目。
- 按“每分钟评审时间解决的拒绝数”排序三个消耗维护者注意力的闸门,而非最便宜优先(那会把方向问题埋在机械流程下):效率(方向检查 > 基于大小的风险标签 > 代码正确性评审)、工作量(方向检查 > 大小风险标签 > 代码正确性评审)、价值(代码正确性评审 > 方向检查 > 大小风险标签)、合规成本(方向检查 == 大小标签 > 代码正确性评审)。方向检查领先,因为约三分之二的被拒 agentic PR 根本不需要读代码。当可信的重复贡献者针对已接受 issue 发小改动时,把代码正确性评审提到第一位——方向问题在 PR 打开前已答,跑顺序比读代码更贵。
- 第 7 步:写关闭与陈旧策略。明确什么自动关闭、什么永不。可辩护的界线:只自动关闭等待报告者而报告者已停止回复的条目;绝不关闭等待维护者的条目——被机器人关闭的已确认 bug 等于告诉报告者其证据一文不值。配置清扫:仅限 waiting-on-reporter 状态、豁免 confirmed 与 blocked 状态、关闭前警告、首轮 dry-run 以先知道爆炸半径。每次关闭都带原因并说明如何重开。每个时钟锚定到具名等待方而非抽象条目。
- 第 8 步:自动化分类,绝不自动化首次回复。先确定性地自动化机械层:从改动路径填 area 标签、从表单打 type、向负责团队请求评审、运行陈旧时钟。每个有文档的机器学习分诊部署都保留人类为最终决策者:把模型辅助当作打分与建议层,绝不自主接受、拒绝或关闭。先复制两个模式:自动化“谁值班”而非“决定什么”(Mozilla 把 triage-owner 字段同步到轮换日历上的人);把标签集作为受验证产物持有,使自动化无法发明标签或覆盖人工工作。把第一句人话留给人类——响应指标按定义排除机器人回复,报告者也同样打折;自动问候后三周沉默让等待更糟。agent 发分诊评论时在评论中披露。
- 第 9 步:发布、跑试点、测量。把政策写进仓库(紧邻 contributing guide)、从入口表单链接、在项目自己的渠道公告一次。与用户一起对新系统跑一次真实分诊场次,处理 15-20 条并计时——这产生第 2 步推迟的每条分钟数,并暴露设计错误(缺失状态、歧义标签、不适配的回复模板)。从未执行过一次的政策只是草稿。首季度每月重跑 `triage-baseline.py`,对照三个起始目标迭代(均为本技能自设基线,非行业基准,有一季度数据后替换为项目自身趋势):未分诊占比低于开放条目 10%;已发布首次响应目标在至少 90% 条目上达成;季度净流入 ≤ 0。迭代到它们成立,或把已发布承诺降到能成立的水平。绝不单看计数指标:CHAOSS 指导将这些度量限制在“主要由人类驱动”的活动;机器生成量下,关闭率与关闭时间可能改善而真实维护者负担上升。每个计数配一个人工驱动信号:排除机器人与作者自回复的首次响应,以及若一人离开还有多少人能覆盖分诊。有持久记忆时存储持久决策:产能数字、约定响应目标、标签轴及定义、路由出 tracker 的类别、容量闸门触发条件、声明为范围外的请求;下次评审就是与这些做 diff。
- 按顺序产出五件交付物,每件经用户确认后再做下一件,绝不一次性静默完成:1) 基线——第 1 步数字、一句话解读、逐条还是聚类的判断。2) 分诊政策——已发布文档:什么属于 tracker、响应目标、状态及含义、何时关闭、谁分诊、容量闸门触发条件。3) 标签变更清单——创建、重命名、合并、删除,各带一句定义及其轴。4) 入口变更清单——要新增或重写的表单及必填字段、chooser 路由条目、安全路径、要启用的自动化,各带应节省的分诊分钟。5) 值班与闸门设计——具名人员与班次长度的轮换、升级规则、PR 闸门顺序。所有交付物使用项目自己的词汇:真实标签字符串、真实渠道、真实维护者姓名。
- 避免六种失败模式:空想目标(两名志愿者承诺 24 小时响应)→ 发布基线支持的数字;休眠轮换(一年没人跑过的文档化排班)→ 给它一个 owner 和存活检查,失效就大声退役;优先级作秀(全是 priority/high)→ 两三级,按后果定义;大爆炸迁移(新标签、旧表单、旧保存视图)→ 标签、表单、视图、自动化一次迁移;把分诊当修复(一场花在调试一条上)→ 时间盒,分诊是排期不是工作本身;未测量的重设计(新流程不知是否有效)→ 每月重跑基线。
适用边界 · 注意事项
- 不要逐条分诊具体条目、策展首次贡献队列、评审代码或处理行为准则事件——这些路由到别处(首次贡献路径、重复问题进文档、敌意行为、范围决策、更广的度量框架)。
- 不要为实际产能为零的项目设计标签体系——诚实的交付物是削减入口并发布维护模式声明。
- 不要复用 issue 流程处理 PR,也不要在没有安全通道时把漏洞细节留在公共 tracker。