一套跑在 Claude Code 上的个人工作操作系统。存储是纯 markdown + git,没有数据库、没有服务、没有账号。 手机上随手丢进 Discord 的一条链接、一份 PPT、一句待办,会被自动抽取、判类、套模板, 最后以一个 pull request 的形式落进仓库等我 review。
| 痛点 | 这里的做法 |
|---|---|
| 任务杂而多,散落在微信、邮件、脑子里 | 所有行动项汇聚到 tasks/TASKS.md 这一个台账,格式由脚本强制校验,ID 唯一 |
| 每天的资料格式五花八门:网页、Word、PPT、PDF、录音 | scripts/intake/extract.py 统一抽成纯文本,再交给 wb-intake 消化 |
| 存了等于没存,三个月后回头找不到 | 强制模板 + YAML frontmatter,机器校验,按 PARA 归档,索引自动生成 |
| 手机上看到有用的东西,回到电脑就忘了 | Discord #inbox 频道随手丢,桥接服务轮询取回,Claude 自动消化并开 PR |
三个入口汇到同一条管道。中间只有一步 —— wb-intake 技能负责抽取、判类、套模板 ——
产物分流到四个去处。每一次消化的终点都是一个 pull request,而不是直接写进主干:
人工闸门是这套系统里唯一不可省略的一环。
这个系统每天真正的写入者是 Claude,不是我。写进 CONTRIBUTING.md 的规则,
如果只是一段自然语言的叮嘱,几十轮会话之后一定会被稀释。所以有一条元规则:
每条规则都必须有一个能自动跑的检查(Rule 2),并且有一个检查专门验证这件事本身
—— all_rules_have_checks.py 会扫描规则列表,任何一条没有对应检查的规则都会让 CI 变红。
一条命令 python3 scripts/run_checks.py 跑完全部检查。绿了,说明骨架完整。
一个决策值得写进 design/ 的判断标准只有一条:将来的我会问"当时为什么这么定",
而答案不在代码里。
单人使用、没有运维预算、坏了只能自己修。选 Discord 而不是 Telegram / iMessage,
是因为需要多频道分流(#inbox / #tasks / #daily / #refs),
以及将来加多个机器人各司其职的空间。飞书 / 企业微信在国内网络和 Office 预览上确实更贴合,
但第一天就要自己维护一座桥,违背"先跑通再加复杂度"。
真正的约束不是功能,而是"写入者是 agent"。markdown + git 让每一次改动都是一个 diff
—— 这是人工闸门能成立的前提。全文检索就是 grep,没有依赖、没有服务、没有账号,
十年后 cat 还能读。代价是复杂查询要写脚本,以及文件数长到几千时得再加索引。
官方插件配置全部做完后 bot 始终不回消息。排查下来是它走 Discord gateway(WebSocket),
而这台机器上 WebSocket 走不通:DNS 被污染到一个 Facebook 段的 IP,修了 DNS 之后 IP + SNI 层同样被挡。
逐条实测七种写法后结论很干净 —— 卡住的只有 WebSocket,REST 完全正常。
于是改成零依赖 Python 定时轮询 Discord REST API,urllib 原生读 https_proxy。
这次排查的判据不是"连上了",而是 Discord 网关握手后必发的 HELLO(op:10) 帧。
只看"连上了"会得到假阳性 —— 三个进程都卡在 SYN_SENT 却看起来像在运行。
选一个不会骗人的判据,是这类网络问题里唯一省时间的做法。
ProgramArguments 必须写解释器的真身路径,不能写 /usr/bin/python3 那个 shim,否则 TCC 权限判定会挂在错误的二进制上。
治理机制(规则必须有检查、agent-loop / agent-verify 契约、保持 CLAUDE.md 简短)
提炼自此前的 DASGPT 项目与自建的 claude-project-toolkit;
"收件箱 → PR"这个管道形态借鉴 DASGPT 的 Reference Scout。
也就是说,这不是从零设计的一套流程,而是把两个真实项目里已经被验证过的做法,
收敛成一个单人可维护的最小骨架。