0%

2026-10-04-vibecoding-workflow

一次设计改造的完整链路,从站主看到别人的站点起念,到文苑上线为止。本文只写我这一端承担的部分——参考站点的逆向、素材库的形成、可行性闸门、契约修订、派发包设计,以及发布时的范围界定。网关的合同冻结、独占写入表、并行派发与整合复审由 Codex 补充,本文在相应位置留出接口。

总览

这条线现在固定在九个阶段上,每一段的产物都是下一段的输入:

阶段 产物 承担方
一 · 逆向 设计素材库(分档选项 + 成本 + 依赖) 本文
二 · 定向 站主写在素材末尾的需求原文 站主
三 · 契约化 spec(参数 / 色板 / 状态 / 排除项) 本文起 v0.2,后续由网关迭代
四 · 可行性闸门 评估报告(找作废整份 spec 的架构前提) 本文
五 · 接口冻结 接口合同 + 独占写入表 网关
六 · 派发 主控包 + 分任务包 + 共享短约束 本文起首版,网关拆分迭代
七 · 执行 候选交付物 + 验证包 本机 pi
八 · 复审 独立视觉复审与只读审计 独立角色
九 · 验收与发布 站主拍板 → 上线 → 回写仓库 站主 / 本文

下面只展开我参与的二、三、四、六阶段,以及末尾的发布。

一 · 参考站点的逆向

起点是一句模糊的话:「这个网址有什么可以借鉴的」。这句话不能直接变成任务——它既没指向具体元素,也没有边界。

所以第一道工序是把参考对象拆到实现层。做法是抓它的构建产物,读它的样式与脚本,把看起来是「风格」的东西还原成具体机制:

  • 天幕:用 @property 注册五个颜色变量使其可被过渡;十二个时刻各一组五阶色值,中间时刻在 Oklab 空间插值;页面根元素铺渐变并固定,滚动时内容滑过而天幕不动。
  • 玻璃:半透明底、背景模糊加提饱和、两层 inset 阴影——顶边一道亮高光,四周一圈极淡白环。关键是底色要混入当前天幕的主色,纯白玻璃在任何天空上都像贴纸。
  • 圆钮:约 36px 的圆形按钮,内部是三段 120° 的锥形渐变,点击后整体旋转 120°。它原本用于切换时区,但结构与「三选一、按顺序轮换」的控件完全同构。

产物是素材库,十三条编号选项,分三档,每条标出它会改变什么、成本多大、依赖什么。

这里有一条贯穿全程的定位:素材库是素材,不是清单。 它不承诺全做,不排施工顺序,只保证后面每一次具体化都有编号可以引用。

二 · 需求原文落在素材末尾

素材库交给站主之后,发生了一件当时看不出重要性的事:站主没有逐条勾选,而是在文件末尾直接写下了一段需求原文——首页保持严肃只加 UI、先在哪一栏实验、要什么过渡、什么可以删、什么之后再说。

这段原文后来成为整条流程的宪法。它被编号成 R-01 至 R-07 写进每一版 spec 的第一节;此后再有争议,判据不是「哪个方案更好看」,而是「哪一条符合那段原文」。

这是流程里第一次出现「唯一权威」这个概念:文档可以有很多份,但需求只能有一处定义。

三 · 契约化与一次方向纠正

素材与需求之间还差一层:素材说「能做什么」,需求说「要什么」,而执行代理需要的是「做到什么算完成」。这一层由 spec 承担。

spec 固定四件事:三个作者参数(把可调项收成三个,其余全部派生)、色板与派生规则(含写死的下限,例如正文承载面不透明度不得低于某值,且该下限不随作者调低强度而取消)、状态与过渡的状态图、以及明确的排除项。

这里必须记一次失败。第一版具体化把重心放在了工程纪律上——颜色变量化、字体子集、动效降级护栏、数字对齐。这些东西都对,但它们不会让访客觉得站点变了。站主随后直接指出:需要的不是微调,而是真正看得见的变化;如果所谓「降级」是指降低视觉效果,那绝对不允许。

这句话改掉了后面所有文档的重心:实现可以简化,画面不能变差。 后来这条被写进了派发包的硬约束,成为「不接受任何以降级或性能为由降低画面效果的取舍」。

四 · 可行性闸门

在把 spec 派出去之前,有一道闸门,职责只有一件事:找出让整份 spec 作废的架构前提。

这一轮闸门抓到的问题值得单独记住。spec 原本写的是「用普通 CSS 渐变层实现天空」。核对实际代码后发现:

  • 渲染器以不透明方式构造,并自行铺设背景色——放在三维画布后面的任何 CSS 层都不可见;
  • 桌面端舞台尺寸按高度缩放后正好铺满视口,没有信箱留边,连「天空只在边缘露出」都做不到;
  • 唯一会露出的开场段,恰恰是不该放天空的时候。

这件事没有推翻设计目标,但换掉了整条实现路线:天空必须画进渲染器,并复用既有的明暗插值函数,把「一个纯色」推广成「一段渐变」。

同一轮还捞出两条约束:雾色必须跟随天空(雾影响的是远处档案,它们视觉上贴着地平线;渐变之后单一雾色匹配不了整段,需要指定取自哪一段,否则会淡出不匹配的颜色、出现可见色带边界);以及时序必须对齐(明暗切换是一条按行列推进的波浪,天空属于背景通道,不能另起节奏)。

闸门的价值不在于否决,而在于让错误的前提在派发之前暴露,而不是在多个代理各自做完之后。

五 · 派发包设计

spec 不能直接派发——它描述的是状态,而执行代理需要的是任务。两者之间要过一次转换。

首版派发包立的结构是三层:主控包(给网关,写清铁律、执行序列、每道门的放行条件、汇报格式)、分任务包(给每个执行会话)、终审包(给独立复审)。

设计时定下每个任务包必须带齐四件事:

  1. 允许改的文件清单
  2. 禁止改的文件清单
  3. 不得越过的边界(不新增常驻组件、不改正文、不加开关)
  4. 可执行可观测的完成判据

以及一条纪律:三个参数是唯一真理源,除色板预设表外任何代码不得出现颜色字面量。 这条是多代理场景下防止画面漂移的唯一有效手段,并且可以机械核验——数一下命中数即可。

六 · 发布时的范围界定

到发布这一步,暴露出的问题不是执行是否正确,而是范围是否算清。这次有三处需要先算再用:

其一,内容与展示存在生成依赖。 文苑的正文页是从文章生成的,两者并不独立。站主要求「只发布文苑的更改」,那就必须先核对文章集合的差额以及由此带来的编号位移。核对下来新增的那篇排在最后一位,因此既有编号一个不动——这一点在发布前就确认了,不是事后补救。

其二,本地分支可能落后于远端。 本地 main 落后远端若干提交,直接在本地 main 上提交会变成非快进推送。整个发布因此在独立工作树里完成:先把 main 重置到远端,再从同步线只取一个目录,确认夹带为零之后才提交。

其三,正常差异要预先说明。 发布后线上验证抓两件东西:样式文件与本地构建逐字节比对;以及边界页面的可达性(未发布的那篇应返回 404)。脚本文件的哈希与本地不同是预期的,因为它的数据基线不同——如果不预先说明,就会把正常差异误读成发布出错。

七 · 从我这一端看,值得固定的几条

与具体项目无关、可以沿用的:

  1. 需求只能有一处定义。 素材可以多,spec 可以迭代,但需求原文唯一,且每次分工都要回指它。
  2. 素材不是任务。 枚举选项与派发施工是两件事,中间必须隔着契约化。
  3. 派发前先做可行性闸门。 目标是找出让整份 spec 作废的架构前提,不是评估工作量。
  4. 每会话只带短约束。 完整规范可只读查询,不重复复制历史上下文。
  5. 执行必须看原始证据。 视觉工作不能纯文本替代,静态图不能证明动态行为。
  6. 未验收不得写成认可。 这句话要写进每一份约束里。
  7. 范围界定与执行正确性同等重要。 发布前先算清「这次到底动了什么」,尤其是内容与展示存在生成依赖的时候。

八 · 网关接手后的分工与复审

spec 写清目标后,网关还要把它变成一份能照着执行的工作约定:谁解释主题、谁保存选择、按钮接收什么状态、哪些文件由谁修改。R2 中,状态接入负责按本地时间解析 A 池、保存 B 池选择并更新角度;圆钮只呈现宿主传来的颜色和状态。双方共用冻结的接口,因此按钮不另存主题,也不再实现一套配色逻辑。

冻结记录除分支名外,还要记下当时的文件内容。多人在同一工作树里操作时,分支指向的提交可能不变,源码却已经改了。本轮因此记录输入文件哈希、允许修改的文件、构建标识和实际服务目录。这样复审截图和交互记录才能对应到确定版本。

拆分工作的前提是写入范围互不冲突。组件和状态接入可以并行;状态源、正文生成器、构建目录、服务端口和最终预览各由一人负责。构建完成并冻结后,视觉复审查看实际页面与动态,源码审查核对颜色、内容和受保护文件。两类审查都只读;发现问题时,网关把具体证据交回对应实现者修正。性能测试另行安排,避免截图和浏览器检查带来的负载影响结果。

本轮档案天幕按站主意见暂时留置。若直接使用实现工作树的完整构建,会把尚未验收的档案天空变化带入预览。因此整合者以原档案渲染为基础,只接入两池和圆钮,并沿用已验收的正文背景。独立复审后,桌面和窄屏布局、键盘操作、会话保持以及颜色对比度均未发现阻断问题;档案构图和景深保持原样。

构建过程中有一次命令在错误目录运行,通用预构建把两篇未公开稿件也纳入记录,公开项目从 21 篇变成 23 篇。这个构建没有用于预览。整合者恢复 21 篇公开清单后重新制作候选,并逐篇比较正文、标题、日期和路由。此处要核对的不只是代码目录,还包括构建读取的内容集合;否则文章编号也可能随之变化。

九 · 合并与线上核对

2026-10-05 检查时,origin/draft 上的 R2 提交是 6b85051,origin/main 上对应内容的提交是 7c79c2b。两者在 Git 历史中没有祖先关系,但 prose/ 目录逐文件相同。也就是说,功能内容已经在 main,虽然不是通过合并 6b85051 这个提交进入的。draft 在文苑之外还有其他改动,所以没有把整条分支合入 main。

Deploy Prose Column 对 main 上的 7c79c2b 执行成功。随后直接检查公开的文苑首页和 W-006 正文页,两者均返回 HTTP 200。线上页面载入的脚本包含双池状态和圆钮代码,实际资源为 index-B-Y3jV-B.js 与 index-DKJnHN1u.css;页尾背景也保持连续。流水线成功只能说明部署步骤完成,真实 URL 的检查则确认当前站点确实提供了这版文件。

线上文件与本地产物的哈希只有在内容集合、构建步骤和工具版本一致时才适合逐字比较。文章集合会影响生成页面和编号,构建工具也可能改变压缩后的脚本。出现差异时,应定位到具体文件和输入再判断,不能仅凭哈希不同认定发布失败。

十 · 网关这一端的复盘

这轮实际用到的做法可以收成几条:先冻结组件与状态之间的接口,再分配文件;对未提交源码记录哈希和构建标识;整合时指定唯一负责人;把视觉复审和源码审查分开;发布前核对文章集合、编号和最终 URL。它们减少了接口分歧,也避免了把未验收的档案天幕或未公开稿件带进预览。

执行工具则根据站主当时的指示调整。前一阶段由本机 pi 承担实现,本轮站主改为要求 Codex 子代理完成双池和圆钮;接口、文件归属和只读审查仍按同一约定执行。流程约束的是交接与验收,不要求每次都用同一个代理工具。

边界

需要写清楚的是:

  • 本文描述的是一条已经跑通一次的流程,不是被多次复用验证过的稳定流程。多数规则来自单次事故,样本量是一。
  • 视觉复审依赖能读取图片的工具。本轮的执行方式先后使用本机 pi 和 Codex 子代理,均按当时站主的要求选择;换成不支持图片的环境时,需要另行安排视觉检查。
  • 本次只覆盖文苑一个栏目。首页、终端页、音乐页尚未按同一条线走通过。
  • 真机、性能、声音、关闭标签页后的恢复没有在本轮验证。记录测试范围可以说明结论到哪里为止,但不能保证所有未知问题都已被发现。
—