React Router 的 Linear 工作流:从 Triage 到 Done 的 Issue 状态机与团队协作规范
React Router 官方仓库的 decisions/ 目录沉淀了一批决策记录(Decision Record),其中编号 0006 的文档专门定义了开发团队如何使用 Linear 来管理 React Router 与 Remix 的日常工作。本篇基于 decisions/0006-linear-workflow.md 完整梳理这套工作流:8 种 Issue 状态的精确定义、状态流转图、标准七步流程与常见例外,并结合仓库中的治理文档与贡献指南,说明这套内部流程与公开的 RFC 治理、PR 审批、发布节奏之间的对应关系,帮助社区贡献者理解自己的 Issue/PR 在官方流程中的位置。
一、文档背景:决策记录与它解决的问题
该决策记录的元信息如下:
| 字段 | 内容 |
|---|---|
| 标题 | Linear Workflow |
| 日期 | 2022-09-06 |
| 状态 | accepted(已接受) |
文档在 Context 部分开宗明义:Remix 开发团队在内部使用 Linear 来管理和排期 React Router 与 Remix 的持续开发,而本文档的目的就是把团队既定的 Linear 工作流程文档化,当任何开发者对流程产生疑问时,有一份权威参照。
值得注意的是,该文档是仓库中一系列决策记录之一。从源码仓库结构看,decisions/ 目录下还有 ADR 模板(包含 Context / Decision / Consequences 三段式结构,以及 proposed / rejected / accepted / deprecated / superseded 等状态标记)以及 0001 到 0016 的多篇决策文档。部分决策文档会被正式文档反向引用,例如 docs/explanation/type-safety.md 引用了 类型推断决策文档,CHANGELOG.md 也引用过 middleware 设计决策文档。AGENTS.md 中同样将 decisions/ 标注为存放决策文档的目录。因此,0006 这篇文档既是流程规范,也是理解该项目工程文化的一扇窗。
二、核心概念:Linear 术语表
原文档在展开流程前,先统一了六个 Linear 术语。这些概念是读懂后文所有状态流转的基础:
| 术语 | 定义 |
|---|---|
| Issue | Linear 系统中的一张工单/任务,描述一个待完成的工作单元 |
| Cycle | 一组目标是在给定的一周周期内完成的 Issue(相当于其他敏捷工作流中的 "sprint") |
| Project | 构成更大范围工作的 Issue 集合(例如一个新特性)。Project 几乎总是跨越多个 Cycle |
| Status | 一张 Issue 所处的状态(Todo、In Progress、Done 等) |
| Assignee | Issue 当前的负责人——表示预期由谁来采取下一步行动以推进该 Issue |
| Label | 一张 Linear Issue 可被赋予一个或多个标签,用于过滤/检索 |
这套术语有一个关键的工程含义:Assignee 不是"这件事的所有者",而是"下一个该行动的人"。这一设计直接服务于后文 In Review 状态下 assignee 在作者与评审者之间来回切换的机制。
三、状态定义:整个工作流由 Status 字段驱动
原文档明确指出,Linear 工作流由 Status 字段治理,其全部取值为 8 种:
| 状态 | 精确定义(原文语义) |
|---|---|
| Triage | Issue 尚未被评审过,团队还不知道是否真的会做这件事 |
| Backlog | Issue 已被接受为"我们想做"的事项,但当前没有排期计划 |
| Todo | Issue 已被排入某个具体的工作 Cycle |
| In Progress | Issue 正在当前激活的 Cycle 中被主动开发 |
| In Review | 工作已完成,PR 已打开,正在接收评审反馈 |
| Needs Feedback | 开发者被阻塞,需要他人反馈后才能继续 |
| Done | Issue 已完成并合并(注意:这不意味着已发布 release) |
| Canceled | Issue 不会被做了 |
这 8 个状态值得逐一对照仓库中的公开流程来理解:
- Triage → Backlog 的评审动作,对应 GOVERNANCE.md 中"Steering Committee will triage issues regularly"的公开承诺;
- In Review 状态与 docs/community/contributing.md 中"PR 需要至少两位 collaborator 批准才能合并;若 PR 作者本身是 collaborator,则算作一票"的规则衔接;
- Done ≠ Released 的区分,对应 DEVELOPMENT.md 描述的独立发布流程——合并进
main/dev只是进入下一个 SemVer 版本的候选,真正的发版是另一套流程。
四、总体流转图:一张图看懂状态机
原文档给出了一张 mermaid 流程图,完整继承如下(可直接渲染):
graph TD
A(Github/Discord/???) -->|intake| Triage
Triage -->|accepted| Backlog
Triage -->|rejected| Canceled
Backlog -->|planned| Todo
Todo -->|picked up| InProgress(In Progress)
InProgress -->|PR| InReview(In Review)
InProgress -->|stopped| Todo
InProgress -->|blocked| NeedsFeedback(Needs Feedback)
NeedsFeedback -->|unblocked| InProgress
InReview -->|larger changes| InProgress
InReview -->|small comments| InReview
InReview -->|merged| Done
从图中可以提炼出三条主干路径与三条回退路径:
- 主干路径:
Github/Discord/??? → Triage → Backlog → Todo → In Progress → In Review → Done。注意入口是"intake"(接收),即所有工作项统一从 GitHub Discussion、Issue、PR 或其他渠道流入 Triage。 - 回退路径一:
In Progress → Todo(开发中途停下,放回队列)。 - 回退路径二:
In Progress → Needs Feedback → In Progress(阻塞与解阻的往返)。 - 评审回路:
In Review → In Review(小评论在状态内自我消化)、In Review → In Progress(大改动退回开发)。 - 两个终止态:
Triage → Canceled(评审即拒绝)和In Review → Done(合并完成)。
五、标准流程七步详解
在流程图之外,原文档还给出了一个更细粒度的"标准 Issue 生命周期",共七步:
- 建单(Triage):当一个想法或 bug 修复通过 GitHub Discussion / Issue / PR 被发现时,创建一张处于 Triage 状态的 Linear Issue 来跟踪任务。
- 要求:Issue 必须包含恰当标题,以及指向 GitHub 原始出处的链接(可追溯性)。
- 团队评审(Triage → Backlog / Canceled):Issue 由团队评审,其中大型变更和新 API 的最终审批权在 Michael/Ryan(项目核心维护者)手中。
- 决定推进 → 移入 Backlog;
- 决定不做 → 移入 Canceled,并且必须同时在 Linear Issue 与原始 GitHub 出处两处给出拒绝理由(内部留痕 + 对外回应,避免社区 Issue 石沉大海)。
- 排期(Backlog → Todo):定期地,Backlog 中的 Issue 被规划进某个 Cycle 并移入 Todo。
- 认领(Todo → In Progress):在激活的 Cycle 期间,开发者认领工单开始工作,将其移入 In Progress。
- 提交评审(In Progress → In Review):工作完成并打开 PR 后,开发者把 Issue 移入 In Review,并把 assignee 指派给应当执行评审的那个人——再次印证了前文"Assignee = 下一个该行动的人"的设计。
- 评审往返(In Review 内循环):若需要反馈,评论留在 PR 上,工单可以在 assignee 之间来回切换,但状态始终保持在 In Review。
- 只有当反馈要求大规模改动时,Issue 才退回 In Progress。
- 完成(In Review → Done):PR 合并后,Issue 移入 Done。
原文档特别强调:"这并非绝对流程,会有例外",并列举了三类典型例外,这是理解该工作流"松紧度"的关键:
- 小 bugfix 可跳级:如果 GitHub 上的 Issue 是个小 bug 修复,可以绕过 Triage 直接进 Backlog,甚至如果开发者在当前(或即将开始的)Cycle 有容量,直接进 Todo——即小修小补不需要走完整漏斗;
- 阻塞即换人:开发者被阻塞时,把 Issue 移入 Needs Feedback 并把 assignee 指派给能解除阻塞的人;
- Backlog 中的"僵尸单":有些 Issue 在被接受并移入 Backlog 很久之后被放弃,这种情况下任何时候都可以把它移入 Canceled。
这三条例外体现了一个务实原则:流程服务于流动,而非制造官僚——工作量越小、确定性越高,走的仪式就越少。
六、Ongoing Processes:让状态机持续运转的例行机制
状态机不会自己转动。原文档最后定义了五类周期性动作,它们是整个工作流的"心跳":
- 统一入口:任何来自 GitHub、Discord(或其他渠道)的想法/bug,都可以放入一张 Triage 状态的 Issue 等待评审;
- Triage 评审节奏:Michael 和 Ryan 应定期(原文建议"每周?")评审 Triage 中的 Issue,将工单移入 Backlog 或 Canceled:
- 被接受的工单应被赋予合适的 Labels 和/或归入 Project(对应前文术语表,Labels 用于过滤检索,Project 用于跨 Cycle 的大特性管理);
- 被拒绝的工单,拒绝理由必须同时写进 Linear 工单和原始出处(如 GitHub);
- Cycle 规划:Michael/Ryan(及团队)决定某个 Cycle 做什么,把工单从 Backlog 移入 Todo 并指定 Cycle;
- 评审义务:所有团队成员应定期(原文建议"每天?")检查指派给自己的工单,及时给出评审/反馈,保证工单持续流动;
- 从队列取活:所有团队成员在激活的 Cycle 期间应始终从自己的 Todo 队列取任务——而不是随意挑选。
最后一条尤为重要:它把"开发者自主挑活"约束为"从已排期的 Todo 队列消费",使得 Backlog 成为规划层、Todo 成为执行层,Cycle 成为时间层,三层职责清晰分离。
七、与仓库公开治理体系的对齐
这套内部 Linear 流程并非孤立存在,从仓库其他文档可以确认它与对社区公开的治理体系互为表里:
- 入口一致:GOVERNANCE.md 规定所有 bug 必须有"最小可运行复现",SC(Steering Committee)定期 triage issues,并用
Accepting PRs标签标记欢迎社区 PR 的工单。社区侧的 GitHub 工单处理,正是 Linear 侧 Triage 状态的输入源。 - 大特性的漏斗一致:GOVERNANCE.md 定义了 Stage 0(Proposal)到 Stage 5(Stable)的 RFC 分阶段过程,其中 Stage 1 之后会移除
accepting-prs标签并加上🗺️ Roadmap标签——这与 Linear 流程中"被接受的工单获得 Label 和 Project"的动作同构。 - 评审规则一致:docs/community/contributing.md 要求 PR 获得两位以上 collaborator 批准、bug 修复必须附带测试(指向 integration/bug-report-test.ts 的失败集成测试范式)、有用户可见影响的 PR 必须附带 change file(
pnpm run changes:add,生成到packages/<package>/.changes/)。这些规则解释了 In Review 状态下"small comments 留在状态内、larger changes 退回 In Progress"的判定依据。 - Done ≠ Released 一致:docs/community/contributing.md 将发布流程单独指向 DEVELOPMENT.md,印证了 Done 状态只覆盖"已合并",发布是另一条流水线。
需要说明适用前提:0006 文档撰写于 2022 年(Remix 与 React Router 合并之前),其中"Michael/Ryan 拥有最终审批权"等具体人员职责反映的是当时的团队结构;当前仓库的 GOVERNANCE.md 已演进为包含多名成员的 Steering Committee 模型。但 Triage → Backlog → Todo → In Progress → In Review → Done 的状态骨架与"评审义务、周期规划、从队列取活"的例行机制,仍是理解该项目内部工作组织方式的核心参照。
八、小结
0006 决策文档 的价值在于它把一个开源项目"看不见的内部机制"显式化了:
- 一个 Issue 的完整生命周期由 8 个状态精确刻画,每个状态都有明确语义,尤其是 Triage 的"未知"、Backlog 的"已接受未排期"、Done 的"已合并未发布" 这三处最容易产生误解的边界;
- 标准七步流程规定了动作的先后(先建单后评审、先排期后认领、先 PR 后 In Review、先评审后 Done)以及 assignee 的语义("下一个该行动的人");
- 三类例外(小修跳级、阻塞换人、僵尸单取消)保证了流程对轻量工作的弹性;
- 五类 Ongoing Processes(统一入口、定期 Triage 评审、周期规划、每日评审义务、从 Todo 队列消费)保证状态机不会停滞。
对于 React Router 的贡献者而言,理解这套流程的实际收益是:当你提交一个 bug 报告 或打开 PR 后,能够准确预期它处于官方流程的哪一段、下一步由谁推动、以及为什么一个 Backlog 状态的工单可能需要等待整个 Cycle 的规划节奏。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0623
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00