跑起来·自愈锻造台(run-fix-forge)
> 交付标准是「真的跑起来了」,不是「给出几种可能的原因」。
何时使用
用户说出下面任意一类话,就该用这个技能:
- 「跑不起来 / 起不来 / 启动失败 / 一运行就退出」
- 「npm install 报错 / pip 装不上 / 依赖冲突 / 版本对不上」
- 「构建失败 / build 报错 / 编译不过」
- 「端口被占用 / Address already in use / EADDRINUSE」
- 「Cannot find module / ModuleNotFoundError / command not found」
- 「换台机器就跑不了 / 我这儿能跑,线上不行 / 新同事环境搭不起来」
- 「Docker 起不来 / compose up 失败 / 容器一启动就退出」
不适用:业务逻辑 bug、性能优化、代码重构、安全加固。这些不是"跑不起来"的问题。
核心原则(这是本技能与"给建议型"技能的分界线)
- 先分层,再动手。 90% 的时间浪费在错误层级上修东西。先用
env_probe.py定位是环境层 / 依赖层 / 配置层 / 代码层 / 运行层,再针对性处理。 - 验收标准唯一:健康探测通过。 进程
nohup出去不等于起来了。必须healthcheck.sh返回 0,或明确的失败证据。 - 每一步都留痕。 用
report.py add记录试过什么、结果如何。避免"我刚才改了啥来着",也让别人能看懂。 - 改完就固化。 修好不是终点,
forge_run.py生成run.sh+ENVIRONMENT.md才算交付——否则下一个人在同一个坑里再摔一次。 - 该止损就止损。 连续 3 轮相同层级失败就停下来汇报,不要无限试错。见「止损规则」。
工作流:五步闭环
第 1 步 · 诊断(只读,不改任何东西)
python3 scripts/env_probe.py <项目目录>
输出:技术栈、卡在哪一层、阻塞项清单(带修复动作)、端口占用、缺失的环境变量、启动命令候选。
完整结果落在 <项目>/.runfix/diagnosis.json。
python3 scripts/report.py add --path <项目目录> \
--step "环境体检" --status fail --cmd "env_probe.py ." \
--note "2 处阻塞:node_modules 未装 / 端口 3000 被占" --layer dependency
退出码 1 表示有阻塞项,0 表示没有明显阻塞。
> 网络不通时加 --offline 跳过依赖源探测;CI 里用 --json 拿结构化结果。
第 2 步 · 按层级修复
诊断结果里每个问题都带 fixHint,直接照做。一次只改一处,改完立刻验证——批量改动会让"到底哪个改动起作用了"变成谜。
高频修复动作速查见 references/failure-patterns.md。
完整流程与判据见 references/playbook.md。
每修一处就记一笔:
python3 scripts/report.py add --path <项目目录> \
--step "安装依赖" --status ok --cmd "npm install" --note "锁文件与 package.json 不一致,重装后恢复" --layer dependency
第 3 步 · 验收(唯一标准)
# HTTP 服务
bash scripts/healthcheck.sh --port 3000 --path /health --retries 30 --interval 1 --log-file <日志路径>
# 更严格:要求响应体包含指定内容
bash scripts/healthcheck.sh --url http://127.0.0.1:8080/health --expect-body ok --retries 30
# 纯 TCP 服务(数据库、消息队列、RPC)
bash scripts/healthcheck.sh --port 5432 --retries 10
# 同时校验进程存活 + 日志无致命错误
bash scripts/healthcheck.sh --port 5000 --pid-file .runfix/app.pid \
--log-file .runfix/app.log --fail-on "Traceback|Fatal|panic:"
退出码 0 = 健康,1 = 不健康(自动打印日志尾部),2 = 参数错误。
没有通过探测,就不许说"修好了"。
第 4 步 · 固化(把运气变成能力)
python3 scripts/forge_run.py <项目目录> \
--start-cmd "npm run dev" --port 3000 --health-path /health
产出:
| 产物 | 作用 |
|---|---|
run.sh |
一键启动:环境校验 → 装依赖 → 构建 → 启动 → 健康探测 → 失败自动打印日志 |
.env.example |
从代码里扫出来的环境变量清单,键名进版本库,真实值不进 |
ENVIRONMENT.md |
环境交付清单:版本要求、端口、启动命令、已知问题、排障速查 |
scripts/healthcheck.sh |
一并复制过去,保证 run.sh 在别的机器上也能独立跑 |
生成后必须真的执行一次 ./run.sh,确认它能把服务拉起来。没验证过的 run.sh 只是个许愿。
第 5 步 · 交付报告
python3 scripts/report.py render --path <项目目录> --format html -o <项目目录>/.runfix/report.html
python3 scripts/report.py render --path <项目目录> --format md -o <项目目录>/.runfix/report.md
报告包含:技术栈、卡点层级、体检发现(问题 → 修复动作)、逐步修复记录(时间 / 命令 / 结果)、交付物清单、防复发建议。HTML 版是单文件、零依赖,可直接发给同事或附在工单里。
分层诊断法
问题永远出在这五层之一,从上往下排查,不要跳层:
| 层级 | 典型症状 | 首选动作 |
|---|---|---|
| 环境层 | command not found、版本不对、网络不通、磁盘满、权限不足 |
装工具链 / 切版本(nvm、pyenv)/ 配镜像源 / 清空间 |
| 依赖层 | Cannot find module、ModuleNotFoundError、版本冲突、锁文件不一致 |
重装依赖、对齐锁文件、必要时删 node_modules 重来 |
| 配置层 | 入口文件不存在、环境变量缺失、端口写错、路径硬编码 | 补 .env、修入口路径、端口改为可配置 |
| 代码层 | 语法错误、导入错误、类型错误、编译失败 | 看完整堆栈,定位到文件行号再改 |
| 运行层 | 启动即退出、端口被占、连不上数据库、OOM | 看日志、查端口、验外部依赖连通性 |
判据很简单:下层没清干净,就别往上层猜。依赖没装好却去改代码,是浪费时间的主要方式。
止损规则
遇到以下情况,停止自动尝试,向用户汇报并给出证据:
- 同一层级连续 3 次失败 —— 说明诊断假设错了,回到第 1 步重新体检。
- 需要凭据但没有 —— 数据库密码、私有 registry token、API Key。不要猜,直接问。
- 修复动作具有破坏性 —— 删库、改生产配置、降级系统包。先确认再动。
- 超过 15 分钟没进展 —— 汇报当前状态、已排除的假设、下一步建议,把决策权交回用户。
汇报格式:
卡在:<层级> · <具体问题>
已试:<动作 1/2/3> → 结果
需要:<缺失的信息或权限>
建议:<下一步>
脚本清单
| 脚本 | 作用 | 依赖 |
|---|---|---|
scripts/env_probe.py |
只读诊断,输出结构化 JSON | Python 3.8+,零第三方依赖 |
scripts/healthcheck.sh |
健康探测(HTTP / TCP / 进程 / 日志关键字) | bash + curl 或 python3 |
scripts/forge_run.py |
生成 run.sh / .env.example / ENVIRONMENT.md | Python 3.8+ |
scripts/report.py |
修复过程留痕 + 渲染 MD / HTML 报告 | Python 3.8+ |
全部支持 --help。env_probe.py 与 forge_run.py 只在标准库上实现,装完 Python 就能跑,不会为了排障先引入一轮新的依赖问题。
安全边界
env_probe.py只读,不修改、不安装、不联网(--offline可完全断网)。forge_run.py生成文件时会覆盖同名产物,覆盖run.sh需显式--force。.env与.runfix/属于本地产物,不要提交到版本库;.env.example只放键名与占位值。healthcheck.sh只做探测,不杀进程、不改配置。
一个完整例子
用户:这个 Node 项目我拉下来 npm run dev 就报错,起不来
1. 诊断 python3 scripts/env_probe.py ./proj
→ 阻塞:node_modules 缺失(依赖层)
→ 警告:端口 3000 被占用(运行层)
→ 缺失环境变量:DATABASE_URL
2. 修复 npm install → 记一笔 ok
lsof 查 3000,杀掉残留进程 → 记一笔 ok
写 .env 补 DATABASE_URL → 记一笔 ok
3. 验收 bash scripts/healthcheck.sh --port 3000 --path /health
→ ✓ 健康:200
4. 固化 python3 scripts/forge_run.py ./proj --start-cmd "npm run dev" --port 3000 --health-path /health
→ 生成 run.sh / .env.example / ENVIRONMENT.md
→ 执行 ./run.sh 复跑一遍,确认干净环境下也能起来
5. 交付 python3 scripts/report.py render --format html -o .runfix/report.html
→ 发报告给用户
设计说明
市面上同类技能大多止步于"分析原因 + 给出建议",用户在第 3 步仍然得自己试。本技能把"建议"换成"验收":
- 用可执行的诊断替代"你看看是不是版本问题"
- 用健康探测退出码替代"应该好了吧"
- 用固化的 run.sh 替代"下次记得先 xxx"
排障真正贵的地方不是那一次修好,而是同一个坑被第二个人、第三次踩。run.sh 和 ENVIRONMENT.md 就是把这一次的时间买断。