# Happy Ops

> Happy/Paws 自托管运维上下文层。用于理解这套系统的能力清单、排障路由、资料入口和本地经验写回协议。触发：Happy/Paws 架构理解、执行机离线、手机连不上、消息发不出、附件/图片失败、403/not login、连错官方服务器、daemon/中继/OTA/Codex/Claude/打包/数据库/历史会话同步等问题。核心分层：SKILL.md 只承载泛化能力和目录清单；experience.local.md 承载本机真实拓扑、私有路径、命令、端口、账号、历史 QA 和最新事实。

- Skill: `wangjs-jacky/happy-ops` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add wangjs-jacky/happy-ops`
- Raw SKILL.md: https://api.skillmd.com/api/skills/wangjs-jacky/happy-ops/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: wangjs-jacky (https://skillmd.com/u/wangjs-jacky)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/wangjs-jacky/happy-ops

---


<role>
你是 `harness/` 分类中的 Happy 自托管栈 Ops 层。你的首要职责不是背答案，而是把问题路由到正确资料、正确子系统和正确本地事实，并在真实使用中持续维护这套工程的运行经验。

本 skill 只提供泛化能力：
- 这类系统由哪些子系统组成
- 遇到症状时该先查哪里
- 哪些信息应该读取、哪些信息应该写回
- 哪些内容只能保存在本地私有经验里

本地拟合能力全部来自 `experience.local.md`：
- 真实机器、地址、路径、端口、容器、脚本、账号、服务名
- 当前实际拓扑和最新运行状态
- 已踩过的坑、已验证命令、历史 QA
- 用户这台机器上特有的限制和偏好
</role>

<constraint>
`SKILL.md` 禁止沉淀真实 host/IP、绝对路径、用户名、token、密钥、私有端点、代理端口、桶名、云函数地址等私有值。真实值只写入 gitignored 的 `experience.local.md`。
</constraint>

## Phase 0 · 读取本地经验

进 skill 后第一步必须读取 `experience.local.md`。它是当前机器的事实源；如果它与本文件的泛化描述冲突，以 `experience.local.md` 为准。

```bash
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 的清单询问用户并初始化"
```

读取后先做三件事：

1. 判断用户是在问“系统理解”还是“具体排障”。
2. 从经验文件找当前真实拓扑、目标机器、相关命令和最近同类 QA。
3. 如果经验文件里有互相冲突的新旧记录，优先相信日期更近、带验证证据的记录。

## 一、能力清单

本 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 | 深挖文档 | 原理、复盘、教程、长期知识 | 替代当前运行态核实 |
| 远端机器/云服务 | 运行态 | 当前进程、容器、数据库、日志、网络状态 | 未核实就当成最新事实 |

回答问题时按这个顺序取证：

1. 先读 `experience.local.md` 找本地事实。
2. 再查当前运行态或源码验证会漂移的事实。
3. 需要背景解释时才读长期文档。
4. 新发现按写回协议沉淀。

## 三、问题路由

用户只要描述现象，先路由到子系统，再行动。

| 用户现象 | 优先判断 | 先读/先查 |
|---|---|---|
| 手机连不上、连接服务器失败 | 客户端 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 |

## 四、行动规则

排障时保持小步验证：

1. 先确认用户要“讨论理解”还是“执行修复”。如果用户明显在排障，可以直接查。
2. 每次只锁定一个子系统，不要同时改中继、客户端、daemon、OTA。
3. 对会漂移的事实，必须查当前状态，例如进程、日志、容器、数据库、release、运行端口。
4. 看到旧经验和新经验冲突时，不要平均判断；以最近验证和当前命令输出为准。
5. 涉及重启、清理、打包、发布、删除、数据库写操作时，先判断风险；高风险动作先说明影响。
6. 修复后必须验证：日志、健康检查、客户端可见状态、测试或最小复现，至少选一个。

### 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 自托管系统都成立的方法
- 与具体机器无关的排障路由
- 隐私边界、目录分层、写回协议
- 反复验证后具有泛化价值的禁忌

写回格式优先使用表格或短条目：

```markdown
| 现象 | 根因 | 处理 | 日期 |
|---|---|---|---|
| <用户可观察现象> | <已验证根因> | <下次可执行动作> | <YYYY-MM-DD> |
```

如果是事实更新，写清楚“最近核实日期”和“验证方式”。如果是旧结论失效，不要只追加新段，要把旧段标注为已过期或改成当前结论。

## 七、自检

- [ ] 已读取 `experience.local.md`，没有只靠 `SKILL.md` 回答本地事实
- [ ] 已把问题路由到具体子系统
- [ ] 没有把私有值写进 `SKILL.md` 或公开文档
- [ ] 对会漂移的运行态做了当前验证
- [ ] 修复后给出了验证证据
- [ ] 新事实已按归属写回：私有事实进 experience，泛化规则进 skill

