“这个 API 的返回结果和 Figma 设计稿看起来不一样吧?”
周五,发布前的最后时刻。Slack 里的一条消息让整个团队停了下来。
PM 一直在认真更新 Jira 工单。设计师一直在打磨 Figma 文件。工程师一直在全速推进 PR。每个人都在各自的领域做着最好的工作——然而,当一切汇合的那一刻,认知的偏差暴露无遗。
接下来的情节可以预见:周五傍晚的 Slack 考古。“这个规格到底是在哪里决定的?""这个 API 和原始工单不一致——是谁改的?“没有人能回答,因为做出决策时的上下文从未被记录在任何地方。
我们陷入这种”没有人有错,一切却在着火”的困境,比我们愿意承认的次数要多得多。Beaket 正是从那段经历中诞生的。
规格说明天生就会”说谎”
不是规格说明本身有问题,而是它赖以存在的结构有问题。
信息天然就分散在不同的地方——PM 住在 Jira,设计师住在 Figma,工程师住在 GitHub。这很正常,每个工具在自己的领域都是最优解,你不应该试图改变这一点。
问题出在把所有这些信息复制到一个”唯一事实来源”的行为上。
当你把内容誊写到 Notion 或 Wiki 的那一刻,信息就变成了两份。当其中一份被更新时,另一份就变成了谎言。一份不再维护的规格说明会丢失过去决策背后的理由,逐渐沦为一件与实际实现越来越脱节的遗物。
这不是态度问题,而是结构性问题。只要副本存在,漂移就不可避免。
连接,而非复制
因此,我们放弃了”把一切集中到一处”的思路。再造一个 Wiki 只会通向同样的结局。
Beaket 做的事情是在已有信息之间建立关联。
你不需要把 Figma 设计稿或 GitHub 讨论复制到 Beaket 中。每个工具继续作为其领域内的事实来源。Beaket 只是通过”为什么做出了这个决策”这一上下文,将这些来源连接起来。
具体来说,它围绕三种节点来结构化项目决策:
- Spec — 业务需求。我们要构建什么,为什么?
- Brief — 设计决策记录。从设计角度做了什么决策,为什么,缺少它会出什么问题。
- ADR — 技术决策记录。为什么选择这个方案?考虑过并否决了哪些替代方案?
这三者通过边相互连接,形成一张决策图谱。你不需要在 Beaket 中编写详尽的规格说明。你只需记录”决定了什么”、“为什么”以及”它与什么相关联”——仅此而已。
“少写”原则
坦率地说,这是我们在产品内部争论最多的一点。
“难道不应该让用户写更多细节吗?“这个问题当然会被提出来。但一旦允许详细书写,你就又造了一个 Wiki。而 Wiki 终将腐烂。
所以我们有意在 Beaket 中植入了一条约束:少写。
判断标准很简单——六个月后的你,会不会回来找这条理由? 会的话就写下来,不会就不写。参数列表和实现步骤交给 GitHub。Beaket 只保存”为什么”的最小单元。
这是一个刻意的取舍。Beaket 永远不会成为一个全面的设计文档工具。这是有意为之。
Ready 标记:一次握手,而非审批
还有一个我们很庆幸做了的机制。
当一份 Spec 编写完成后,设计师和工程师各自独立地设置一个”Ready”标记。设计师表示”从 UI 角度,我理解了需求”;工程师表示”从技术角度,我理解了需求”。只有当两个标记都被设置后,该 Spec 才会变为”Ready”状态。
这不是审批流程,而是一次握手。
不是”我读过了”,而是”从我的角度来看,可以开始了”。这是从机制上防止在需求模糊时就开始实现的保障。
而且,如果一份 Spec 在被标记为 Ready 之后发生了变更,其影响范围——所有关联的 Brief 和 ADR——会被自动呈现出来。再也不需要翻遍 Slack 历史记录了。
追溯决策的足迹
Beaket 记录的变更历史不仅包括”谁在什么时候改了什么”,还包括”为什么改”。
选中任意一段文字,你就能追溯它是在什么时候、被谁、出于什么原因修改的。我们称之为 Decision Trail(决策足迹)。
这不是什么炫酷的功能。但六个月后,当有人问”这条规格为什么是这样的?“——答案就在那里。仅凭这一点,就能改变团队做出决策的速度。
我们尚不知道的事
我们不认为 Beaket 适合每一个团队。
对于一个坐在同一间办公室、上下文自然共享的小团队来说,它可能是大材小用。对于数百人规模的组织,我们的验证还远远不够。
我们唯一确信的是:丢失决策背后的上下文,必然会产生成本。 而这个成本会随着团队规模的扩大和时间的推移呈指数级增长。
Beaket 是一个从结构上控制这一成本的工具。它不是银弹,更像是一份保险。
如果你的团队也曾遇到过没有人能解释某个设计决策为何如此的困境——不妨从连接一个决策开始,看看它会带你走向何方。