🛠️ 第4章 Codex 的任务地图
📄 一句话概括

手机端不是缩小的桌面端:它只做三件事——收通知、看结论、发新任务。 值守要成立,三个前提得同时满足:叫得醒、看得懂、回得去。 它是桥,不是主力:把「跑完了」送到你眼前,不替你判断该不该合。

📝 本章和前面几章的关系

这一节短,因为结论也短:手机上不该干重活。 但短不等于可以跳过。 任务从「你盯着它跑」变成「它自己跑完通知你」,中间隔着的就是这个入口。 这个转变比它看起来重要——它把「你必须坐在电脑前」这件事取消了。 Demo 里三条推送消息,两条卡在前提上:一条太长,锁屏只剩半句;一条没有 commit,回不去。

一、手机上能干什么、不能干什么

判断依据只有一条:六寸屏加一根手指。所有「能」和「不能」都是这一条的推论。

事 手机上能做 为什么
看它跑完没有 能 一条消息就够
判断结果好不好 能,但要有人写结论 结论得脚本给,不是你看 diff
叫它改一版 能 再发一条任务单
看完整 diff 不能 六寸屏看不了两百行
处理冲突 不能 得在编辑器里看三方合并
决定要不要合 不能,只能延后 该在电脑上先跑一遍测试

「判断结果好不好」那一格要读两遍。 「能,但要有人写结论」——这个「人」其实是脚本。 结论必须由跑测试的那一步生成,不能指望你在手机上读 diff 自己判断。 所以手机能不能用,取决于你的任务有没有「自动结论」这一步。 没有它,手机只能告诉你「跑完了」,而「跑完了」离「做对了」还有一段。

二、值守场景的三个前提

值守这个词的意思是:你不看着它,但你能随时接管。 它要成立,三个前提缺一不可。

前提 具体是什么 缺了会怎样
叫得醒 通知通道通,锁屏可见 跑完了你也不知道
看得懂 结论由脚本给,一句话说清 知道跑完了,不知道对不对
回得去 有 commit 才能回滚 知道不对,但收不了场

三条里最容易漏的是第三条,而且漏在最不起眼的地方:超时的任务。 Demo 里那条超时的没有 commit,因为它根本没跑完。 可它可能已经改了一半——改了一半又没有 sha,你连回哪儿都不知道。 正确做法是把「记 sha」放在开跑之前,不是放在提交之后。 不管成不成,那个 sha 都在。 这是流程问题,不是工具问题——任何任务单系统都该这么设计。

三、它是桥,不是主力

桥的职责是转达,不是决策。 手机把「跑完了」这件事送到你眼前,这一件事它做得很好。 但「合进去」这个动作不该在手机上做。 理由很实在:那一刻你没跑测试、没看完整 diff、没看别人的评论。 三样都没看就合,等于闭眼签字。 一个可操作的分工: 手机上只做两个决定——「继续等」和「叫它改」。 「合进去」永远留到电脑前,哪怕只隔十分钟。 顺带说一句「生态桥接层」这个说法。 手机端常常还兼一个职责:把别的系统的消息接进来——工单系统、群消息、监控告警。 它是个入口,不是个平台。

四、动手 Demo:值守:三条推送消息,卡在三个前提上

这个 Demo 真跑一个值守脚本:三个任务的结果写成三个 JSON 文件,脚本扫目录、拼消息、 再逐条检查三个前提。 消息是真拼的,宽度是真量的(中文算两个字符宽),锁屏一行按四十个字符宽估算。

for f in sorted(os.listdir(os.path.join(base, u"jobs"))):
    j = json.load(fh)
    mm, ss = j[u"秒"] // 60, j[u"秒"] % 60
    m = u"%s %s · %d 分 %02d 秒 · 回滚 %s | %s" % (
        icon[j[u"状态"]], j[u"标题"], mm, ss,
        j[u"commit"] or u"无", j[u"结论"])

fit = [p for p in prefix if U.w(p) <= 40]   # 锁屏放得下几条
has = sum(1 for j in jobs if j[u"commit"])  # 回得去几条

实跑输出:

--------------------------------------------------------------------
值守:三条推送消息,卡在三个前提上
--------------------------------------------------------------------


  ① 三个任务跑完了,谁来告诉你
  --------------------------------------------------------------------
  值守脚本每十秒扫一遍 jobs 目录,把结果拼成一条消息:
  [完成] 改 calc 的除零 · 2 分 14 秒 · 回滚 c1a2f3d | check.py 通过 4 / 失败 0
  [失败] 补 add 的测试并让它覆盖负数 · 1 分 03 秒 · 回滚 9f2b7e1 | check.py 通过 1 / 失败 3
  [超时] 通读 payment 模块 · 10 分 00 秒 · 回滚 无 | 十分钟未出结果

  ② 三个前提,一条一条查
  --------------------------------------------------------------------
  [过] 前提一 能被叫醒        通知通道 1 个,锁屏可见
    [完成] 改 calc 的除零 · 2 分 14 秒                 锁屏一行放得下
    [失败] 补 add 的测试并让它覆盖负数 · 1 分 03 秒    宽 47,放不下
    [超时] 通读 payment 模块 · 10 分 00 秒             锁屏一行放得下
  [不过] 前提二 一眼能判断      2/3 条在四十宽以内
  [不过] 前提三 一键能回滚      2/3 条带 commit
  前提二挂一条:任务名一长,锁屏就只剩半句。前提三挂一条:超时那个根本没产出 commit,回不了。
  ! 两条都是值守最容易漏的地方。第一条靠写标题时手短一点;
  第二条得改流程——跑失败的任务也要能回滚,因为它可能已经改了一半。
  做法是开跑之前先记一个 sha,不管成不成,那个 sha 都在。

  ③ 手机能干什么,不能干什么
  --------------------------------------------------------------------
| 事 | 手机上能做 | 为什么 |
|---|---|---|
| 看它跑完没有 | 能 | 一条消息就够 |
| 判断结果好不好 | 能,但要有人写结论 | 结论得由脚本给,不是你看 diff |
| 叫它改一版 | 能 | 再发一条任务单 |
| 看完整 diff | 不能 | 六寸屏看不了两百行 |
| 处理冲突 | 不能 | 得在编辑器里看三方合并 |
| 决定要不要合 | 不能,只能延后 | 该在电脑上先跑一遍测试 |

  ! 手机是桥,不是主力。它负责把「跑完了」这件事送到你眼前,不负责替你判断该不该合。

最长那条四十七宽,锁屏只剩半句。 这不是文案问题,是「谁写标题」的问题——任务名是你起的,起长了自己受罪。下次写短点。 第三条超时,没有 commit。 这一条暴露的是流程漏洞:sha 记在提交之后,而不是开跑之前。 改法只有一句:开跑先记 sha。 「手机上能判断结果好不好」那一格我写的是「能,但要有人写结论」。 这个「人」是脚本——你的任务里必须有一步生成结论,否则手机只能告诉你「跑完了」。 手机真正省掉的不是时间,是「你必须坐在电脑前等」。 这一点在长任务上价值最大——一个跑四十分钟的活,你可以去开会,回来再看。

30 秒实验

  1. 找一个你真会跑很久的任务,给它配一条通知。 只写三样:成没成、用了多久、怎么回滚。
  2. 把通知发到自己手机上,看锁屏能显示多少字。 超出一行的部分,就是你白写的部分。
  3. 下次跑长任务之前,先 git rev-parse HEAD 记下 sha。 不管成不成,这个 sha 都是你的退路。

常见误区

  1. 「手机能改代码,那就用手机改。」 能改和该改是两件事。 改三行以内可以,改一个函数就不该了——你看不见上下文。
  2. 「有通知就行了。」 通知只说「跑完了」,不说「跑得对不对」。 结论得有人写,通常是一行 通过 4 / 失败 0。
  3. 「超时了重跑一次就行。」 它可能已经改了一半。 超时任务同样要能回滚,所以 sha 要记在开跑之前。
自测三问(点开对答案) 1. 值守的三个前提是哪三个?哪个最容易漏? —— **叫得醒、看得懂、回得去。** **最容易漏「回得去」**,而且漏在超时任务上——它没跑完,所以没有 commit。 2. 为什么「跑失败的任务」也需要能回滚? —— **因为它可能已经改了一半。** **失败不等于什么都没发生**,恰恰相反,失败的任务最容易留下半截改动。 3. 手机上为什么不该做「合进去」这个决定? —— **那一刻你没跑测试、没看完整 diff、没看别人的评论。** **三样都没看就合,等于闭眼签字。**

下一篇 4.4 讲本地与云端怎么分:三个判据,顺序不能换。

相关笔记