# 0.8.5 Project Deployment Runbook `DEPLOYMENT.md` 是每个本地项目自己的部署/运维规范。0.8.5 增加了一个重要场景:**项目完全没有可复用部署经验时,Agent 不应该先编一份看起来很完整、实际上没有跑过的 Runbook,而应该先和用户一起把第一次部署真正跑通,再把实际成功的路径沉淀成 `DEPLOYMENT.md`。** 因此现在有两条入口,最后汇合到同一套成熟流程。 ```text 入口 A:已有部署经验 / 历史命令 ↓ 核对真实环境 ↓ DEPLOYMENT.md ↓ 用户实际验证 ↓ 使用习惯访谈 ↓ 一键脚本 ↓ Agent 闭环部署 入口 B:完全没有部署经验 ↓ 本地项目发现 ↓ 服务器环境发现 ↓ 逐步确认部署需求 ↓ Bootstrap Plan ↓ 尝试部署 / 看日志 / 调试 ↓ 第一次真正跑通 ↓ 把“实际成功路径”总结成 DEPLOYMENT.md ↓ 后续进入与入口 A 相同的成熟流程 ``` ## 一、两种入口 ### 入口 A:从“已有经验”开始 适用于用户已经有: - 历史部署命令; - 旧的部署文档; - 已知服务器目录; - 已知启动命令; - 已知上传方式; - 或者已经存在 `DEPLOYMENT.md`。 Agent 应先核对本地项目和当前 session-bound SSH 的真实环境,再把历史经验整理成可审查、可执行的 Runbook。 这条路径的核心是: > **已有经验 → 核对 → 文档化 → 验证 → 自动化。** ### 入口 B:从“完全不知道怎么部署”开始 适用于用户只有一个本地项目,希望“帮我把这个项目部署到服务器”,但没有可靠的部署命令或 Runbook。 这时不能因为没有 `DEPLOYMENT.md` 就拒绝继续,也不能先凭经验生成一份看起来完整的 Runbook,然后假装那就是正确答案。 这条路径的核心是: > **发现 → 询问 → 尝试 → 看证据 → 调试 → 跑通 → 再文档化。** ## 二、Stage 0:从零开始 Bootstrap 一个项目 ### 0.1 先看本地项目,搞清楚“到底是什么东西” Agent 应先只读检查 LOCAL Workspace,例如: - 项目类型和主要技术栈; - 依赖管理方式; - 构建入口; - 运行时及版本要求; - 程序真正的启动入口; - 构建输出或发布产物; - 运行时必须存在的静态资源、模板、配置等; - 本地配置文件与环境变量引用; - 数据库 / MQ / Redis / 外部服务依赖; - native / OS / architecture 依赖; - migration; - 持久化目录; - 默认端口和健康检查入口。 这里很重要的一点是:**Agent 要自己判断部署时真正需要带哪些东西,而不是默认把整个仓库复制到服务器。** 它应该区分: ```text 只在开发/构建时需要 运行时真正需要 必须由服务器单独维护 必须持久化 暂时无法判断 ``` 如果无法确定,不要擅自删减,应该告诉用户这个点还没有确认。 ### 0.2 再看服务器,搞清楚“这里能不能跑” 只检查当前 Conversation 已绑定的 SSH,不自行枚举或切换服务器。 建议确认: - OS 与 CPU architecture; - 已安装 runtime 以及版本; - Docker / systemd / PM2 / Supervisor 等运行方式; - 当前用户与权限; - 磁盘空间; - 可写目录; - 已经运行的服务; - 已占用端口; - 已有项目目录; - 日志位置; - 是否存在可能冲突的程序。 如果用户已经要求: ```text 部署到某个目录 必须使用某个端口 必须用 Docker 必须以某个用户启动 ``` 这些都应该当成约束先去验证。 如果用户没有要求,Agent 可以根据真实环境提出 1~3 个合理方案,但不要静默替用户拍板。 ### 0.3 不要一次问十几个问题 第一次部署需要用户参与,但不应该变成填表。 推荐交互方式: ```text Agent 先检查一轮 ↓ 已经知道一部分事实 ↓ 只问当前真正影响下一步的一个或几个问题 ↓ 用户确认 ↓ 继续检查 / 推进 ↓ 再问下一处决策 ``` Agent 能自己查到的事情自己查。 用户真正需要决定的是偏好和业务要求,例如: - 这是测试、预发布还是生产; - 远程目录是否有指定要求; - 服务是否需要开机自启; - 是否需要对外暴露端口; - 配置 / secrets 由谁提供; - 数据目录是否必须持久化; - 失败时希望停下来还是恢复; - 是否允许安装系统级依赖。 ### 0.4 形成 Bootstrap Plan,而不是先写假 Runbook 在第一次有副作用的操作前,应先给用户看到一个临时计划: ```text LOCAL - 发现了什么 - 准备使用什么产物 TRANSFER - 准备上传哪些文件/目录 - 上传到哪里 REMOTE - 准备创建/使用哪个目录 - 准备用什么 runtime 启动 VERIFY - 怎么判断程序真的起来了 RECOVERY - 这一步失败如何撤回 ``` 这份 `Bootstrap Plan` 是探索阶段的临时计划,不等于稳定的 `DEPLOYMENT.md`。 第一次部署的确认应该是**逐步确认**。 用户确认“可以先上传到 staging”不代表同时批准: - 安装系统包; - 修改防火墙; - 覆盖其他项目; - 停 unrelated service; - 数据库迁移; - 注册 root systemd service。 当方案发生实质变化时,应重新确认。 ## 三、第一次真正尝试部署 ### 3.1 尽量从可逆步骤开始 优先顺序通常应该是: ```text 确认产物 → 建 staging / 临时目录 → 上传 → 检查完整性 → 准备运行环境 → 尝试启动 → 验证 ``` 不要一开始就覆盖线上目录或停止其他程序。 ### 3.2 运行失败时要看日志,而不是随机试命令 第一次部署大概率会遇到问题。 正确循环是: ```text 执行 ↓ 读取 stdout / stderr / 日志 ↓ 检查进程 / 服务 / 端口 ↓ 根据证据判断原因 ↓ 提出最小修改 ↓ 必要时让用户确认 ↓ 修改 ↓ 重新运行和验证 ``` Agent 应记录真正有价值的信息,例如: - runtime 版本不兼容; - 少了某个运行时文件; - 环境变量不存在; - 工作目录不对; - 启动参数缺失; - 端口被占用; - 文件权限有问题; - native library 缺失; - 数据库连接失败。 不应该为了“硬把服务跑起来”而无依据地不断改服务器。 ## 四、允许明确承认“这个服务器目前跑不了” 这是 0.8.5 的硬原则之一。 如果证据表明当前服务器在已授权范围内无法安全运行项目,例如: - OS / CPU architecture 不兼容; - runtime 无可用版本; - 项目依赖无法在当前系统满足; - 必要基础设施不存在; - 用户没有可用凭据 / secret; - 权限不足; - 资源明显不够; - 端口 / 网络约束无法满足; - 继续解决需要大范围修改系统; Agent 应直接告诉用户: ```text 当前目标服务器在现有约束下无法完成部署。 ``` 然后说明: - 卡在哪里; - 证据是什么; - 已经确认哪些部分可行; - 有哪些现实选择。 **不允许隐藏 fatal log、假装服务启动成功,或者为了不承认失败而不断扩大修改范围。** ## 五、什么时候算第一次部署“跑通” 至少应满足技术层面的证据: - 目标进程 / service 能稳定存活; - 必要端口正常监听; - Health / HTTP 检查通过(如果项目存在); - 最近启动日志不存在阻断性 fatal/error; - 实际运行的是预期产物 / 版本(如果可确认)。 随后把结果交给用户做业务验证。 技术层面跑通不等于业务一定正确。 ## 六、第一次跑通后,再生成 DEPLOYMENT.md 这是从无到有场景和旧流程最大的区别。 Runbook 应来自: > **刚才真实执行成功的路径。** 而不是: > **一开始猜测应该怎么部署的路径。** 建议记录: - 项目和目标服务器; - runtime / 系统前提; - 实际需要的发布输入; - 哪些步骤是用户人工完成的; - 文件传输范围; - 远程目录; - 配置 / secret / 持久化边界; - 启动 / 停止方式; - 端口; - 日志; - Verification; - Recovery / Rollback; - 第一次部署中发现的关键坑。 失败过但最终被证明错误的尝试,不应该写成正常部署步骤;必要时可以放进“Troubleshooting / 已知问题”。 Agent 应先把这份“实际成功基线”展示给用户,用户确认后再调用 `deployment_runbook_write`。 这份 Runbook 此时可以认为: ```text 已经真实跑通过 1 次 ``` 但还不能自动认为: ```text 已经成熟到适合全自动化 ``` ## 七、后续成熟流程 ### Stage 1:Runbook 可读化 `DEPLOYMENT.md` 应继续按实际项目组织,例如: ```text LOCAL TRANSFER REMOTE VERIFY ROLLBACK ``` 允许复合 shell / PowerShell,不要求强行一命令一行。 ### Stage 2:用户实际验证 用户后续真正使用过这份 Runbook,并明确认为稳定,才进入自动化讨论。 一次工具返回 `exit code 0` 不代表流程自动成熟。 ### Stage 3:使用习惯访谈 Runbook 中有命令,不等于脚本必须执行。 每个步骤先确定: ```text AUTOMATE KEEP MANUAL EXTERNAL / HAND-OFF NOT IN NORMAL RUN ``` 脚本边界由用户真实习惯决定。 ### Stage 4:一键脚本 只有: ```text Runbook 已验证 + 自动化覆盖范围已确认 ``` 才生成一键入口。 脚本也需要真实试运行和用户确认。 ### Stage 5:Agent 闭环部署 成熟后用户只需要提出部署目标,Agent 可以在已批准范围内: ```text 检查本次输入 → 自己执行脚本 / 已验证流程 → 检查进程 / 端口 / Health / 日志 → 分析真实 Change Set → 告诉用户重点测试什么 → 等待用户业务验收 ``` 用户反馈异常时: ```text 收集现象 → 查看日志和服务状态 → 对照本次 Change Set → 定位 → 修复或进入恢复决策 ``` 风险较高时向用户提供: ```text 继续排查 给我回滚命令 由你执行回滚 ``` 如果执行回滚,回滚后仍必须重新验证旧版本是否真的恢复健康。 ## 八、完整生命周期 ```text ┌─────────────────────┐ 已有命令 / 旧流程 ─────→ │ 核对并形成 Runbook │ └──────────┬──────────┘ │ │ 无部署经验 │ ↓ │ LOCAL 项目发现 │ ↓ │ REMOTE 环境发现 │ ↓ │ 逐步确认需求 │ ↓ │ Bootstrap Plan │ ↓ │ 部署 / 日志 / 调试 │ ↓ │ 第一次真实跑通 │ ↓ │ 总结实际成功路径 ────────────────────┘ ↓ DEPLOYMENT.md ↓ 用户实际验证 ↓ 自动化边界访谈 ↓ 一键脚本验证 ↓ Agent 自主发布 ↓ 技术自检 ↓ Change Set + 测试重点 ↓ 用户业务验收 ↙ ↘ 正常 异常 ↓ ↓ 完成 诊断 / 修复 / 回滚 ↓ 再验证 ↓ 完成 ``` ## 九、安全边界 无论处于哪一阶段,都保持这些规则: - 一个 Conversation 只操作当前 session-bound SSH; - 不自行寻找别的服务器; - 不把 LOCAL 路径误当成 REMOTE 路径; - 高风险操作继续走 Harness 原生审批; - 不静默修改系统包、防火墙、反向代理、数据库或凭据; - 不覆盖 unrelated project / service; - 不把“脚本退出成功”当成“部署成功”; - 不把“技术自检成功”当成“用户业务验收成功”; - 不为了完成任务而伪造健康状态。 ## 十、最终原则 - **有经验时:从已有经验整理到 Runbook。** - **没经验时:先把项目真正部署跑通,再从事实生成 Runbook。** - **Bootstrap Plan 是探索计划,不是假装稳定的 Runbook。** - **第一次部署要反复基于日志和状态证据调整,而不是随机试命令。** - **服务器确实跑不了时必须明确承认。** - **Runbook 中有命令,不代表脚本必须自动执行。** - **自动化边界由用户习惯决定。** - **脚本成熟后,Agent 才进入自主执行、验证、验收、诊断和恢复闭环。**