muse-agent-example/docs/运行手册.md
zizi 713cc45c63 重构(数据库): 迁移链压扁为单基线并精简测试至保留集
- 51 个增量迁移文件压扁为 V0001__基线.sql 完整快照(结构+种子+授权),
  等价门禁:旧链全量执行库与基线库 pg_dump 逐字节一致
- 剔除 pg_dump 固化的 public schema 超级用户归属断言(muse_maint 无权执行)
- 测试删减至保留集:备份往返 2 + 预算 2 + 租约 2 + 基线建库 1
- 租约/预算夹具改共享库,消除按例克隆建库
- 修复共享库三类既有污染:账本注入残留(系统管理)、失败触发器残留(评测)、
  建表残留(正式变更事务),发布包迁移文件名硬编码改动态核对
- 全量数据库验收 722 passed / 0 failed / 0 errors(main 基线为 24F+291E)
- 运行手册登记基线模式改表流程与账本校验和同步
2026-09-22 10:18:51 +08:00

100 lines
7.3 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!-- 导航元信息: {"内容描述": "系统组成、启动停止、备份恢复、资源更新与排障入口", "使用场景": "日常启动/停止、备份恢复、更新资源、排障时", "使用要求": "运行形态或运维入口变化时"} -->
# 运行手册
> 新版 Muse(agent-example 单用户作者工作台)的日常运行、备份与排障入口。能力状态与边界见文末。
## 1. 系统组成
| 组件 | 位置 | 说明 |
|---|---|---|
| 作者工作台服务 | 本机 `muse 服务`(uvicorn 127.0.0.1:8080) | 唯一正式写入口;静态工作台随资源包发布 |
| 正式内容库 | infra(100.64.0.8:5433)PG 实例,库 `muse_migration_1fe755ea37684f9d926f3a0cb3e9c7f2` | 作品/章/正文/规则/样例权威;用途角色 muse_app/eval/maint 隔离 |
| 资源包 | `src/muse/资源/`(构建身份见 `工具/环境预检.py`) | 角色/操作/提示词/工作台前端 |
| 应用配置 | `配置/本机正式.toml`、`配置/本机维护.toml` | 非敏感实例配置由 Git 管理,不依附临时工作树;模板为 `配置/应用.example.toml` |
## 2. 启动与停止
```bash
# 从 agent-example 仓库根启动;先确认 8080 没有其他实例。
# 日志、凭据和文件资产放在工作树之外,不能随迁移草稿一起清理。
umask 077
nohup .venv/bin/python -m muse 服务 配置/本机正式.toml \
>> "$HOME/.local/share/muse/正式环境/服务日志.log" 2>&1 &
echo $! > "$HOME/.local/share/muse/正式环境/服务.pid"
# 健康
curl -s http://127.0.0.1:8080/health # {"status":"alive"}
curl -s http://127.0.0.1:8080/ready # 含数据库连通
# 停止:先核对记录的 PID 确为本机正式.toml 对应服务,再终止该 PID。
pid=$(cat "$HOME/.local/share/muse/正式环境/服务.pid")
ps -p "$pid" -o command=
# 人工核对后执行:kill "$pid"
```
浏览器访问 `http://127.0.0.1:8080`,用配置的口令文件登录。当前作者 ID 为 `1`,与正式库的 7 部作者作品一致;不得用模板的 `author-local` 替代。
### 配置与凭据恢复
- 版本化范围:`配置/本机正式.toml`、`配置/本机维护.toml` 保存非敏感配置及受控引用;仅创建文件不代表已经提交 Git。
- 本机受控根:`~/.local/share/muse/正式环境/`(目录 0700,凭据文件 0600)。三个数据库角色分别使用 `muse_app.连接.txt`、`muse_eval.连接.txt`、`muse_maint.连接.txt`;工作台使用 `工作台口令.txt`。
- 可选连接池参数:在 `["数据库"."连接池"]` 节声明 `最大连接`(1–100)与 `等待秒`(0.1–60.0)可显式覆盖默认值(生产 4、评测 2,等待 2.0 秒);只调优当次部署的借还行为,不改变数据库目标身份。
### 数据库结构变更(基线模式)
自 2026-09 起迁移链已压扁为单基线:`数据库/迁移/V0001__基线.sql` 是全部表结构、系统种子数据与角色授权的完整快照。不再为每个结构变更新增迁移文件。
日常改表流程:
1. 动手前先备份(`muse 备份`);
2. 修改 `V0001__基线.sql`(同步结构、种子或授权变化);
3. 在正式库手动执行对应的 `ALTER TABLE ...` 等语句(以维护角色连接);
4. 跑 `make 数据库测试` 验证底座能用新基线建出可用库。
账本说明:`muse_migration` 表仍存在并登记 V0001 的校验和,用于备份清单核对与 `muse 管理系统状态` 的版本一致性检查。修改基线文件后必须同步更新账本校验和,否则启动诊断会报 `changed_versions`:
```sql
-- 以 muse_maint 连接正式库执行;<sha256> 为新基线文件的 sha256
UPDATE muse_migration SET checksum='<sha256>' WHERE version=1;
```
旧备份兼容:迁移链压扁前创建的备份,其清单登记 51 步账本,与新基线代码不匹配;若需恢复,先切回压扁前的代码版本执行恢复,再重新做一次新格式备份。压扁当日的最后一次旧格式备份建议长期保留。
- infra 凭据副本:SSH `个人-minione-ubuntu-infra-4c16g120g`,目录 `/opt/infra/private/muse-agent-example/`。恢复时复制所需文件到本机受控根并核对权限;禁止输出凭据内容到日志或提交明文凭据。
- 正式连接仅使用 PG `100.64.0.8:5433`,带 `keepalives=1 keepalives_idle=15 keepalives_interval=5 keepalives_count=3`。Redis 与本项目无关。
- 原迁移目录中的库外原文、草稿和切换回执尚未找回。当前文件根是恢复后新建的目录,不代表原文件资产已恢复。
## 3. 备份与恢复
```bash
# 完整备份(数据库 + 当前配置声明的文件根);输出目录必须全新。
# 备份客户端要求 pg_dump 17:`brew install libpq@17`(镜像源可用,keg-only),
# 执行时前置 PATH=/opt/homebrew/opt/libpq@17/bin:$PATH。项目自身 NOWAIT 取锁已提供
# 冲突保护,不再向 pg_dump 传 --lock-wait-timeout(PG17 客户端下会自杀)。
.venv/bin/python -m muse 数据维护 备份 配置/本机维护.toml <全新备份目录>
.venv/bin/python -m muse 数据维护 核对 <备份目录>
# 恢复必须使用明确指向全新空库的维护配置,不能覆盖正式库。
.venv/bin/python -m muse 数据维护 恢复 <新空库维护配置> <备份目录> --预期备份ID <backup_id>
```
服务器级备份:infra 容器原生 PG 17 `pg_dump`,以 `muse_maint` 执行;恢复后的数据库归档保存在 `/opt/infra/private/muse-agent-example/backups/`,本机副本在 `~/.local/share/muse/正式环境/数据库备份/`。数据库单独归档不等于包含库外文件的完整备份,`pg_restore --list` 和哈希一致也不等于完成恢复演练。
## 4. 资源与代码更新
改代码/技能/提示词后:`工具/构建资源包.py` 重建 → `工具/环境预检.py` 取新 resource_build_id → 更新应用配置 `发布身份` → 重启服务。
## 5. 排障
| 症状 | 处置 |
|---|---|
| 长连接被掐(Tailscale 空闲断连) | 连接串须含 `keepalives=1 keepalives_idle=15 keepalives_interval=5 keepalives_count=3`(守卫白名单已含) |
| 写请求 SCOPE_DENIED | 缺 Origin 头或来源不在 `允许来源`;浏览器正常访问即自带 |
| 工作台 404 资源不存在 | 资源包未随新身份重建/配置身份过期,按第 4 节处理 |
| 连接被拒 target_denied | 端点/参数/角色不属于获准实例;检查连接串与允许实例记录 |
| 章后任务「抽取提案」失败 `模型协议错误`,证据里输出 token 等于上限 | 该提供方通道的模型默认产出推理(如 Claude 经 chat-completions 的 `reasoning_content`),把输出上限吃满;改用 Messages 协议(`anthropic`)并声明 `thinking="off"`,实测网关会映射为 `{"type":"disabled"}` |
## 6. 能力状态与验证边界
R2 主体交付、历史数据处置和原测试/恢复结果统一见[R2 改造历史留痕](实现回顾/R2改造历史留痕.md),本手册不再保存过程验收状态。该历史归档不代表当前部署健康、旧库所有写权限关闭、129 项功能全量验证或生产无缺陷。
日常操作使用前述稳定配置与受控入口;运行状态以当次检查为准,文学效果、协议替身、真实宿主与模型证据分别判断。恢复合同见[备份与恢复入口](系统架构/新版设计/迁移与验收.md#备份与恢复入口),不把历史恢复摘要或新建文件根当作已找回原库外资产。