本 skill 只提供泛化能力:
- 这类系统由哪些子系统组成
- 遇到症状时该先查哪里
- 哪些信息应该读取、哪些信息应该写回
- 哪些内容只能保存在本地私有经验里
本地拟合能力全部来自 experience.local.md:
- 真实机器、地址、路径、端口、容器、脚本、账号、服务名
- 当前实际拓扑和最新运行状态
- 已踩过的坑、已验证命令、历史 QA
- 用户这台机器上特有的限制和偏好
Phase 0 · 读取本地经验
进 skill 后第一步必须读取 experience.local.md。它是当前机器的事实源;如果它与本文件的泛化描述冲突,以 experience.local.md 为准。
SKILL_NAME="happy-ops"
DIR="${CLAUDE_SKILL_DIR:-}"
[ -z "$DIR" ] && DIR="$(dirname "$(find "$HOME/.claude" -name SKILL.md -path "*/$SKILL_NAME/*" 2>/dev/null | head -1)")"
[ -z "$DIR" ] && DIR="$HOME/.claude/skills/$SKILL_NAME"
EXP="$DIR/experience.local.md"
[ -f "$EXP" ] && sed -n '1,260p' "$EXP" || echo "experience.local.md 缺失:先按本 skill 的清单询问用户并初始化"
读取后先做三件事:
- 判断用户是在问“系统理解”还是“具体排障”。
- 从经验文件找当前真实拓扑、目标机器、相关命令和最近同类 QA。
- 如果经验文件里有互相冲突的新旧记录,优先相信日期更近、带验证证据的记录。
一、能力清单
本 skill 管的是一类“移动端 + 自托管中继 + 执行机 + 上游模型/CLI + OTA”的个人运维系统。具体实现名、地址和命令不要写死在这里。
| 能力 | 你要做什么 | 本地事实从哪里读 |
|---|---|---|
| 架构理解 | 解释数据路径、OTA 路径、执行机路径、认证路径之间的边界 | experience.local.md 的拓扑、机器、客户端、OTA 段 |
| 中继排障 | 判断服务、数据库、反代、附件下载、同源 token 是否正常 | 中继段、已知坑、健康检查命令 |
| 执行机排障 | 判断 daemon 是否在线、是否连对中继、是否被错误环境拉起 | 执行机段、daemon 日志、LaunchAgent/保活记录 |
| Claude/ReClaude 排障 | 判断代理、CA、Keychain/登录态、GUI/SSH 启动域问题 | 认证脚本段、not login QA、reclaude QA |
| Codex 排障 | 判断 Codex 是否继承了错误代理、二进制是否可执行、thread 是否可恢复 | Codex QA、代理环境、CLI 修改记录 |
| OTA 排障 | 区分 App OTA 握手、bundle 存储、runtimeVersion、channel、历史锁定 | OTA 段、发布命令、近期 preview/production QA |
| 数据库/消息排查 | 找到中继数据库、会话表、消息表、解密所需 key 的来源 | 数据库排查段、解密经验 |
| 打包/发布判断 | 判断该走本地打包、云端打包、release、还是 OTA | 客户端构建发布段、打包冻机 QA |
| 经验沉淀 | 把新事实写回正确位置,不污染可分享 skill | 本文件的写回协议 |
二、目录清单
先把资料分层,不要把所有信息都塞进回答里。
| 位置 | 角色 | 允许内容 | 不允许内容 |
|---|---|---|---|
SKILL.md |
泛化能力骨架 | 子系统模型、排障路由、写回协议、隐私边界 | 真实 IP、私有路径、token、端口、云资源名、个人账号 |
experience.local.md |
本地拟合层 | 真实拓扑、机器、命令、脚本路径、历史 QA、最新验证结果 | 会进 git 的公开说明 |
| 项目源码 | 行为事实 | 真实实现、日志、测试、构建脚本 | 为了记录经验而改无关代码 |
| Obsidian/wiki | 深挖文档 | 原理、复盘、教程、长期知识 | 替代当前运行态核实 |
| 远端机器/云服务 | 运行态 | 当前进程、容器、数据库、日志、网络状态 | 未核实就当成最新事实 |
回答问题时按这个顺序取证:
- 先读
experience.local.md找本地事实。 - 再查当前运行态或源码验证会漂移的事实。
- 需要背景解释时才读长期文档。
- 新发现按写回协议沉淀。
三、问题路由
用户只要描述现象,先路由到子系统,再行动。
| 用户现象 | 优先判断 | 先读/先查 |
|---|---|---|
| 手机连不上、连接服务器失败 | 客户端 endpoint、证书信任、反代、中继健康 | 拓扑、中继段、客户端构建段 |
| App 显示执行机离线 | daemon 是否存在、是否连对中继、机器是否被错误 env 拉起 | 执行机段、daemon 日志、离线 QA |
| 在线但消息发不出 | 会话进程、上游模型认证、代理、socket/reconnect | 执行机段、Claude/Codex QA |
not login / 403 |
认证环境、Keychain/GUI 登录态、代理/CA 注入 | Claude/ReClaude 段 |
| 连到官方服务器 | HAPPY_SERVER_URL 或等价中继变量缺失 |
执行机脚本段、连错中继 QA |
| Codex stream 断开 / spawn 失败 | Codex 代理、二进制、app-server thread 恢复 | Codex QA、CLI 日志 |
| 图片/附件 401 或打不开 | public URL、同源 token、上传/下载链路 | 中继 env、附件 QA |
| OTA 不更新或检查失败 | runtime/channel/target lock/manifest/bundle/手机日志 | OTA 段、OTA QA |
| 要查历史会话/消息 | 中继数据库 + 本地 session key,不默认找本机库 | 数据库排查段 |
| 要打包 APK | 先判断是 OTA、云端打包还是本地打包;注意机器资源限制 | 客户端构建段、打包 QA |
四、行动规则
排障时保持小步验证:
- 先确认用户要“讨论理解”还是“执行修复”。如果用户明显在排障,可以直接查。
- 每次只锁定一个子系统,不要同时改中继、客户端、daemon、OTA。
- 对会漂移的事实,必须查当前状态,例如进程、日志、容器、数据库、release、运行端口。
- 看到旧经验和新经验冲突时,不要平均判断;以最近验证和当前命令输出为准。
- 涉及重启、清理、打包、发布、删除、数据库写操作时,先判断风险;高风险动作先说明影响。
- 修复后必须验证:日志、健康检查、客户端可见状态、测试或最小复现,至少选一个。
Happy/Paws PC/Web 默认发布
- 完成 Happy/Paws 的 PC/Web 页面、交互或样式改动并通过验证后,只要用户没有明确要求“只改代码”或“不要部署”,就直接发布到
experience.local.md记录的既有自托管 Web 目标,不再额外询问。 - 不要为这类发布另建 Vercel Preview 或临时 Tunnel;只有用户明确要求临时预览时才使用新的预览地址。
- 发布前读取本地经验中的当前主机、目录、资源存储和回滚信息,优先使用仓库正式发布脚本或已验证的等价原子流程。
- 发布后同时验证 release marker、入口引用资源的最终响应和真实浏览器运行态;三者一致才算完成。
五、硬性禁忌
这些规则来自本类系统的通用风险,不依赖具体机器:
- 不要把真实基础设施信息写入
SKILL.md。 - 不要只因为 daemon 在线就判定上游模型可用;在线、认证、模型请求是三层不同问题。
- 不要只因为 SSH 能连就判定 GUI/Keychain 登录态可用;SSH 域和 GUI 域可能不同。
- 不要让不同 agent 的网络代理互相继承;Claude/ReClaude 代理和 Codex/其他 CLI 代理需要分开判断。
- 不要把 OTA 和数据中继混为一谈;它们通常是两条独立链路。
- 不要把归档会话等同于杀掉执行机进程;是否会回收要看实现和当前进程树。
- 不要在资源紧张机器上贸然启动重型构建;先看经验文件里是否已有资源限制或替代流程。
- 不要把历史经验当作当前事实;关键运行态要现查。
六、写回协议
完成一次理解、排障或修复后,判断是否要写回。
应该写回 experience.local.md 的内容:
- 新机器、新路径、新端口、新脚本、新服务名、新容器名
- 新的现象 -> 根因 -> 下次处理规则
- 当前命令验证过的运行态
- 某个旧经验已失效或被新流程取代
- 用户明确表达的本地偏好或禁忌
应该固化进 SKILL.md 的内容:
- 对所有同类 Happy 自托管系统都成立的方法
- 与具体机器无关的排障路由
- 隐私边界、目录分层、写回协议
- 反复验证后具有泛化价值的禁忌
写回格式优先使用表格或短条目:
| 现象 | 根因 | 处理 | 日期 |
|---|---|---|---|
| <用户可观察现象> | <已验证根因> | <下次可执行动作> | <YYYY-MM-DD> |
如果是事实更新,写清楚“最近核实日期”和“验证方式”。如果是旧结论失效,不要只追加新段,要把旧段标注为已过期或改成当前结论。
七、自检
- 已读取
experience.local.md,没有只靠SKILL.md回答本地事实 - 已把问题路由到具体子系统
- 没有把私有值写进
SKILL.md或公开文档 - 对会漂移的运行态做了当前验证
- 修复后给出了验证证据
- 新事实已按归属写回:私有事实进 experience,泛化规则进 skill