接棒 Baton · 通宵施工总纲
这份文档是给你(施工 AI agent)看的,不是给人看的。 生成时间:2026-07-30 深夜 | 验收时间:2026-07-31 早上 你从这里开始读,读完再去读同目录下的其他文件。
#0. 三十秒搞清楚状况
- 你是谁:一个无人值守的施工 agent。今晚没有人在旁边。你问不到任何人。
- 你要干什么:从零建一个叫「接棒 Baton」的 Next.js + Supabase 全栈项目,做到能上线、能点、有真数据,并在东京 VPS 上增量搭一层 Agent 服务。
- 你有多久:约 9 小时(T+0 → T+9h)。
- 明早会发生什么:人类会打开
baton.saveme505.help、git log、测试报告、AC 完成矩阵。他会一眼看出你是真做完了还是糊弄的。 - 规矩:SDD(规格先行)+ TDD(测试先行)。没有规格不许写代码,没有失败的测试不许写实现。
- 不确定的东西:不许猜、不许编。记进
docs/night/blockers.md,做下一件事。
#1. 铁律(违反任何一条 = 今晚白干)
#1.1 关于诚实
- 禁止假通过。不许
.skip、.only、不许空断言、不许把失败用例注释掉、不许为了让测试变绿去改测试的断言。发现做不到,就写进 blockers.md 并诚实标FAILED。 - 禁止 mock 掉被测对象本身。数据库集成测试就要真连 Supabase;解析测试就要真喂一个 PDF。允许 mock 的只有:外部 LLM/embedding API(走 fixture)、时间、随机数。
- 禁止在报告里写"已完成"而实际没有对应的绿色测试。AC 矩阵里每一条的状态必须能被
npm run test的输出反查到。 - 不确定就标不确定。你写进文档的每一条技术结论,要么有命令输出为证,要么标
[未验证]。
#1.2 关于不可逆操作
- ⛔ 禁止在东京 VPS 上执行任何删除/停用操作。具体地:不许
rm、不许systemctl stop|disable|mask、不许pip uninstall、不许kill、不许覆盖任何已存在的.env、不许改任何已存在的 systemd unit。- 服务器上现在跑着拉斐尔(飞书 bot)、Telegram bot、LINE bot、ashare-auto-git。它们必须活着到天亮。
- 「删掉拉斐尔、Hermes 重装」这件事人类明天亲自做,今晚不碰。你只做增量新增。
- ⛔ 禁止
vercel deploy/vercel --prod/ 任何 CLI 直接部署。上线的唯一路径是:改本地 → git commit → git push origin main → Vercel Git 集成自动部署。 - ⛔ 禁止跑任何 Vercel 写类命令前不备份
.env.local。要跑先cp .env.local .env.local.bak。(历史教训:media-studio 曾因此丢了四个孤本值。) - ⛔ 禁止在 Supabase 上删表、删数据、改动任何非
bt_前缀的东西。你今晚新建的所有表必须叫bt_*,所有函数必须叫bt_*。Leo-hub 里有别的项目在用,碰坏了是灾难。 - ⛔ 禁止把任何密钥的明文写进代码、写进 git、写进文档、写进 commit message。密钥只出现在
.env.local(本地,已 gitignore)和 Vercel 环境变量里。 - git 只往
main推你自己新建的baton仓库。不许碰本机任何其他仓库。
#1.3 关于工程
- 所有数据库访问必须走单一入口
src/lib/db.ts的scopedQuery(employeeId)。任何地方直接supabase.from('bt_...')而不带员工过滤 = 跨人数据泄漏 = 这个项目的核心卖点当场破产。这条要有专门的测试守着(见02-TDD规程)。 - service role key 只能出现在服务端。任何客户端组件里出现
SUPABASE_SERVICE_ROLE_KEY= 立即回滚。 - 中文:所有代码注释、commit message、文档、UI 文案一律简体中文。变量名/函数名用英文。
- 提交节奏:小步提交。每个 AC 至少两个 commit(
test:先,feat:后)。禁止一个巨型 commit。 - 每完成一个阶段立刻 push。阶段 1 做完就要有线上站可点。不要憋到天亮一次推。
#2. 项目是什么(一句话 + 五个功能)
给小公司每个人配一个 Agent,管住自己手上的资料。同事之间可以互相问对方的 Agent;人走了或者换岗,一键把该给的交出去。
| # | 功能 | 今晚做到哪 |
|---|---|---|
| 1 | 一人一个 Agent(各自独立记忆/资料/互相看不见) | 网页侧的数据隔离全做;VPS 侧建 3 个 Hermes profile |
| 2 | 上传资料,Agent 自动学 | 真上传 → 真解析 → 真切片 → 真 embedding → 真入库 |
| 3 | 飞书私聊问自己的 Agent | 新建独立飞书应用 + 长连接跑通(若时间不够可降级) |
| 4 | 我的 Agent 去问老王的 Agent | 网页侧 /api/ask + 跨人提问日志必须做完;VPS 侧尽力 |
| 5 | 一键交接 | 必须做完做透,这是项目的心脏 |
品牌与视觉(人类已拍板,不要再改)
- 名字:接棒 Baton,英文标识
baton - 视觉:浅色干净风。浅色为主、大留白、克制的商务感,像一个真能卖给小公司的 SaaS。不要深色科技风、不要霓虹、不要玻璃拟态。
- 组件:shadcn/ui + lucide 图标。用 Card / Table / Sheet / Dialog / Badge / Switch / Progress / Tabs / Command / Sonner。
- 交接页是主场,允许做一点克制的动效(勾选时条目飞入右栏、确认成功的微动画)。
#3. 今晚的阶段总表
关键设计:阶段 1 做完就先上线一次,之后每个阶段做完都 push 一次。 早上线早暴露部署问题,也保证无论后面卡在哪,明早都有一个能点的线上站。
| 阶段 | 名称 | 预算 | 起止(T+) | 做完的硬标志 |
|---|---|---|---|---|
| P0 | 环境自检 + 规格落盘 + 建仓 | 45min | 0:00 → 0:45 | docs/specs/ 六份规格写完;仓库建好首推;工具链自检全绿 |
| P1 | 后台五页 + 假数据 + 首次上线 | 2h | 0:45 → 2:45 | 线上 baton.saveme505.help 可点,五页齐全,密码门生效 |
| P2 | 数据层 + 上传解析入库 + 检索 | 2h15 | 2:45 → 5:00 | 真传一份 PDF,真切片,真搜出来,真带出处(第几页) |
| P3 | 记忆条目抽取 + 编辑 + 三开关 | 1h | 5:00 → 6:00 | 从文档自动抽出条目,带出处,页面上能改、能开关 |
| P4 | 交接闭环 + 记录 | 1h30 | 6:00 → 7:30 | 勾一半交接 → 对方确认 → 接手人查得到、没勾的查不到、记录里有完整一行 |
| P5 | 上线收口 + 导航站收录 | 20min | 7:30 → 7:50 | 线上跑的是最终版;hub 导航站有「接棒」这一条 |
| P6 | VPS Agent 层(纯增量)🚨 | 1h | 7:50 → 8:50 | 3 个 Hermes profile 能各答各的;现有服务全部还活着 |
| P7 | 验收包 + 邮件 | 20min | 8:50 → 9:10 | 六份验收文件齐全,Resend 邮件已发出 |
🚨 P6 的特别提醒:写这份文档时实测发现,东京 VPS 此刻正处于一次进行中的高负载风暴(load average 107,CPU steal 94%,journald 因看门狗崩溃重启 3 次,连监控脚本自己都被卡死了)。 P6 的第一件事是体检,不是施工。 健康门不过就整体跳过,只留采证和报告。详见
06-技术资料-服务器Agent层.md开头。
⭐ P0 的特别提醒:有三个架构决策必须在 P0 就定下来(Supabase 密钥方案 / 文件存哪 / embedding key),它们决定后面所有代码怎么写。⛔ 不要拖到 P2 才发现拿不到 key。 详见
04-技术资料-数据层与检索.md§1。
#3.1 闸门规则(Gate)
上一阶段的 AC 没有全绿,不许进下一阶段。 每个阶段结束必须跑:
npm run gate # 见 scripts/gate.sh它会检查:typecheck 通过 + lint 通过 + test 全绿 + 反作弊扫描通过 + 本阶段 AC 全部标记为 PASS。任一项失败 → 不许推进。
闸门失败时的处置(按顺序试,最多 30 分钟):
- 修(正常路径)
- 修不动 → 把这条 AC 降级为
PARTIAL,写清楚差在哪,写进deviations.md,继续下一阶段 - 整个阶段塌方(比如 Supabase 连不上)→ 走 §6 的降级方案,写进
blockers.md,继续下一阶段
绝对不要在一个问题上死磕到天亮。 一个阶段超预算 50% 就必须降级止损。
#3.2 时间超支的取舍优先级
时间不够时,保下面这个顺序(前面的优先保住):
- P1 线上站可点(这是明早第一眼看的东西)
- P4 交接闭环(这是项目的心脏)
- P2 上传检索带出处
- P3 记忆条目抽取
- P7 验收包(再赶也要留 20 分钟做这个)
- P6 VPS Agent 层(最先被砍,砍了写进 blockers 即可,人类明天自己搞)
#4. 文档导航(按这个顺序读)
| 文件 | 什么时候读 | 内容 |
|---|---|---|
00-总纲-给施工Agent.md |
现在 | 你正在读的这份。铁律、阶段、闸门、交付。 |
01-SDD规格规程.md |
P0 开始前 | 规格文件长什么样、AC 编号规则、变更日志格式、六份规格的完整内容 |
02-TDD规程与反作弊.md |
P0 开始前 | 红绿循环怎么强制、测试怎么分层、反作弊脚本、vitest/playwright 配置 |
03-阶段施工单.md |
每个阶段开始时读对应节 | 每阶段的任务分解、要先写哪些测试、DoD |
04-技术资料-数据层与检索.md |
P2 开始前 | 建表 DDL、RLS、混合检索函数、切片策略、坑 |
05-技术资料-前端与流水线.md |
P1/P2 | Vercel Blob 直传、文档解析选型、长任务架构、Next 16 变化、坑 |
06-技术资料-服务器Agent层.md |
P6 开始前 | VPS 现场勘察报告、增量新增方案、飞书新应用、禁止事项 |
07-验收包模板.md |
P7,以及全程 | 明早要交出的六份文件的模板 |
08-可复用资产清单.md |
P0/P1 | 密码门四文件、导航站 PROJECT_META、版本基线、Supabase 接入范式 |
scripts/ 里是可直接复制进项目的脚本;templates/ 里是可直接复制的模板文件。
#5. 项目落地位置与身份
- 本地路径:
~/personal/baton - GitHub:
LeoLee0812/baton,public(这是个开源项目)- 建仓时立刻填 description 和 topics:
knowledge-handoveragent-memoryragnextjssupabasehermes-agentfeishu - 教训:ChatDemo 那次 description/topics 全空,等于把唯一入口废了
- 建仓时立刻填 description 和 topics:
- git 身份:user.name =
<作者>,user.email =<邮箱>(已是全局配置,直接用) - Commit message:中文,带类型前缀(见
02-TDD规程§2) - 线上域名:
baton.saveme505.help - 密码门:走统一 HMAC 门(
HUB_SITE_PASSWORD/HUB_AUTH_SECRET),四个门文件照抄,见08-可复用资产清单 - 数据库:Supabase 项目 Leo-hub,所有表加
bt_前缀 - LLM / embedding:云雾中转(OpenAI 兼容,
https://yunwu.ai/v1)- 对话模型默认
deepseek-v4-flash - embedding 用
text-embedding-3-small - ⚠️ 云雾现在是一个项目一把 key。今晚在云雾后台没法自助新建,先复用一把现有可用 key 跑通,并在
blockers.md里写一条「待人类去云雾后台建baton专属 key 并替换」。
- 对话模型默认
#6. 卡死自救(无人值守最重要的一节)
#6.1 通用规则
- 同一个错误连续失败 3 次 → 停止重试。换方法或降级。
- 单个任务超 20 分钟无进展 → 标 blocked,跳到下一个独立任务。
- 每次 blocked 都必须往
docs/night/blockers.md追加一条,格式见07-验收包模板。 - 环境类问题(装不上包、命令不存在)先试一次替代方案,再降级。
#6.2 预设的降级路径
| 卡在哪 | 降级方案 | 后续影响 |
|---|---|---|
| Supabase 连不上 / 建表失败 | 切本地 .data/baton.sqlite(用 better-sqlite3),保持 db.ts 接口不变,向量检索退化为纯 pg_trgm 式模糊匹配的 JS 实现 |
P1/P3/P4 全部照做,P2 的语义检索标 PARTIAL |
| embedding API 调不通 | 跳过向量列,只做模糊匹配检索,chunk 照常入库 | 检索质量下降,标 PARTIAL |
| PDF 解析包在 Node 22 跑不起来 | 退到只支持 .txt / .md / .docx,PDF 走"检测到扫描件/解析失败"的错误态 UI |
P2 标 PARTIAL,UI 的错误态本来就要做 |
| Vercel 部署失败 | 先确认 Framework Preset(历史坑:Vite 迁 Next 后 preset 不自动改会静默 404);仍失败则本地 npm run build 出静态证据 + 截图,写进 blockers |
明早人类手工点一次重新部署 |
| 自定义域名解析没生效 | 用 *.vercel.app 原始域名交付,写进 blockers |
不影响验收内容 |
| VPS 上任何一步不确定 | 立刻停手。P6 全部降级为「写一份明天照着做的操作单」 | 服务器安全 > 功能进度 |
| 飞书新应用建不了(需要人工在后台点) | 跳过飞书,只做 hermes -p emp_wang -z "..." 命令行验证 |
P6 标 PARTIAL |
#6.3 什么情况下应该直接停下来等天亮
只有一种:你发现自己可能已经破坏了服务器上的现有服务,或误删了本机文件。
这时立刻停止所有操作,把现场记录进 blockers.md 的最顶部,标 🚨 需要人类立即处理,然后只做验收包和邮件,其他什么都别做。
#7. 天亮前必须交出的东西(T+8:50 之后无论如何都要做)
全部放在 ~/personal/baton/docs/night/,并 push 上去:
| 文件 | 内容 |
|---|---|
00-一页纸总结.md |
给人看的。做完了什么、没做完什么、明早先看哪三样、需要人类拍板的事 |
ac-matrix.md |
AC 完成矩阵:每条验收准则 → PASS / PARTIAL / FAILED / SKIPPED + 证据(测试名或截图) |
test-report.md |
npm run test 与 npx playwright test 的完整输出摘要 + 覆盖率数字 |
deviations.md |
所有偏离规格的地方:偏了什么、为什么、影响 |
blockers.md |
所有卡住的点,按严重度排序,每条带「明早怎么处理」 |
worklog.md |
时间线流水账,每 30 分钟一行,让人类能还原你这一夜干了啥 |
screenshots/ |
五个页面 + 交接流程关键步骤的截图(Playwright 截,浅色主题) |
最后一件事:调用 email skill,用 Resend 发一封邮件到 <邮箱>。
- 主题:
[接棒 Baton] 通宵施工报告 · <完成度> - 正文:结论先行 → 完成度概览 → 线上链接(
https://baton.saveme505.help)+ 密码门提示 → 三条最需要拍板的事 → blockers 摘要 - 结尾附 GitHub 仓库链接
#8. 开工前的最后一句
你今晚会遇到很多"要不要偷懒一下"的岔路口。判断标准只有一个:
明早那个人打开这个项目,会不会觉得被骗了?
一个诚实标着 PARTIAL 的功能,比一个假装 PASS 实则空壳的功能有价值一百倍。
现在去读 01-SDD规格规程.md。
来源:沉淀/03-项目方案与交接/接棒-通宵施工包-20260731/00-总纲-给施工Agent.md(整理于 2026-08-18)