Why: U4 ships the managed migration entry; the runbook is the operator-facing contract for inventory/backup/migrate, migration identity and resume rules, verification semantics, and the authorized-window switch sequence. Evidence: backend branch feature/collab-storage-u4-migrator - integration tests green against real PostgreSQL (idempotent rerun, resume, foreign-data refusal, wrong-snapshot refusal, unknown-owner block). Impact: docs only. Refs: proposals/2026-10-11-collaboration-storage-and-distribution.md U4 and section 6.
199 lines
12 KiB
Markdown
199 lines
12 KiB
Markdown
# 团队存储运行手册(协作存储 U1)
|
||
|
||
适用范围:[协作存储与分布式方案](../proposals/2026-10-11-collaboration-storage-and-distribution.md) U1/U2
|
||
(已批准,2026-10-11)落地后的 **team 部署档** 运维与验证。个人 `local` 档(SQLite)
|
||
用法不变,见 [usage](usage.md)。本文是 U1 的固定部署清单、配置合同、迁移映射、
|
||
容量合同、隔离测试方案与 KTD14 副本保护合同的单一事实源;实施状态以各任务卡为准。
|
||
|
||
## 1. 目标实例与固定部署清单
|
||
|
||
| 项 | 值 | 说明 |
|
||
|---|---|---|
|
||
| 部署形态 | svc.sh 管理的 `runtime/<name>` 实例 | 非容器;单机多实例按名隔离 |
|
||
| 当前团队候选 | `runtime/dev`(8788,SQLite)→ 目标切 team 档 PG | 切换窗口与回退按方案 §6,须另行授权 |
|
||
| 数据库(本机验证) | PostgreSQL 18.6 + pgvector 0.8.7(brew) | 本机验证用;正式实例待指定 |
|
||
| 数据库(CI 门禁) | Ubuntu 24.04 apt:postgresql 16 + postgresql-16-pgvector | 版本以 CI job 输出为准 |
|
||
| 缓存/限流 | Redis 8.10.2(本机);CI apt redis-server | 只存可重建状态(KTD10) |
|
||
| 应用制品 | `agent-system` 单二进制(make build) | 拷贝即运行;team 档需 `--tier team` |
|
||
|
||
未知项(正式实例主机、pgvector 正式启用版本、对象存储选型)在正式切换授权前
|
||
必须补齐;本清单不把本机验证环境当作正式部署事实。
|
||
|
||
## 2. team 档配置合同(U2 已实施)
|
||
|
||
启动语义(KTD1 fail-closed):
|
||
|
||
- `tier=team`:必须配置 `dsn` 且认证开启(`auth=on`;`auth=auto` 随 DSN 自动开);
|
||
任一缺失**拒绝启动**。PG 打开失败**拒绝就绪**,绝不回落 SQLite。未配置执行隔离
|
||
(`disableExecTools` 或 `execBackend`)时启动警告(多用户开放前必须补齐)。
|
||
- `tier=local`:SQLite;配置 `dsn` 是配置错误,拒绝启动。
|
||
- `tier` 缺省(auto):现状语义——`dsn` 非空走 PG,否则 SQLite。
|
||
|
||
配置键(四源合并:默认 → 文件 → 环境 → 显式 CLI,与 usage §启动一致):
|
||
|
||
| 键 | env | CLI | 语义(team 档) |
|
||
|---|---|---|---|
|
||
| `tier` | `AGENT_SYSTEM_TIER` | `--tier` | `local` / `team` / 空=auto |
|
||
| `dsn` | `AGENT_SYSTEM_DSN` | `--dsn` | PG 连接串;team 必填 |
|
||
| `auth` | `AGENT_SYSTEM_AUTH` | `--auth` | team 档要求最终为 on |
|
||
| `instance` | `AGENT_SYSTEM_INSTANCE` | `--instance` | 空=主机名:监听地址(多实例必须互异) |
|
||
| `pgMaxOpen` | `AGENT_SYSTEM_PG_MAX_OPEN` | `--pg-max-open` | 每进程最大连接(默认 16) |
|
||
| `pgMaxIdle` | `AGENT_SYSTEM_PG_MAX_IDLE` | `--pg-max-idle` | 每进程空闲连接(默认 8) |
|
||
| `pgConnMaxIdleSec` | `AGENT_SYSTEM_PG_CONN_MAX_IDLE_SEC` | `--pg-conn-max-idle-sec` | 空闲回收(默认 300s) |
|
||
| `pgConnMaxLifetimeSec` | `AGENT_SYSTEM_PG_CONN_MAX_LIFETIME_SEC` | `--pg-conn-max-lifetime-sec` | 连接寿命(默认不限) |
|
||
| `pgQueryTimeoutSec` | `AGENT_SYSTEM_PG_QUERY_TIMEOUT_SEC` | `--pg-query-timeout-sec` | statement_timeout 秒(默认不限) |
|
||
|
||
连接预算(KTD12):预算覆盖全部 API/Worker/LISTEN/migrator/监控连接;
|
||
100 在线用户 ≠ 100 连接。`agent-system config explain` 输出脱敏有效值
|
||
(DSN 密码打码)。启动日志打印 `storage tier: team (dialect=postgres pool=… schema=v…)`。
|
||
|
||
迁移(KTD8,U2 已实施):DDL 与版本登记同事务(中途失败整体回滚,不存在
|
||
「表已建、账本未记」中间态);PG 并发迁移者按会话咨询锁串行化;SQLite 写事务
|
||
`_txlock=immediate` 跨进程排队。库内出现比二进制新的 schema 版本时拒绝启动。
|
||
|
||
## 3. 迁移映射(SQLite → PG,U4 工具消费)
|
||
|
||
| SQLite 侧 | PG 侧 | 备注 |
|
||
|---|---|---|
|
||
| `agent-system.db`(WAL) | 同名逻辑库 | 活跃 WAL 不能只拷 `.db`;一致性备份用 VACUUM INTO |
|
||
| INTEGER 0/1 布尔列 | BOOLEAN | v9/v10/v11 起双方言已分型 |
|
||
| `INTEGER PRIMARY KEY AUTOINCREMENT` | `BIGSERIAL`/`SERIAL` | events、command_audit、audit_events |
|
||
| FTS5 虚表 + 触发器 | tsvector 生成列 + pg_trgm GIN | v4;中文子串走 trigram |
|
||
| `vec BLOB` | `BYTEA` | pgvector 类型切换在 U6,不在本映射 |
|
||
| `<data>/artifacts/` 工件对象 | 本期仍本地目录 + PG 清单 | 共享对象存储在 U5/U9 |
|
||
|
||
RDM 独立业务库与旧 Agent-System 治理库**不在**本映射内;迁移工具(U4)只处理
|
||
Backend 库,非空目标拒绝、同快照才可续传。
|
||
|
||
## 4. 容量合同(验收目标,非性能结论)
|
||
|
||
方案 §3 的量化指标(100 在线 / 300 SSE / 20 执行中 Agent / P95≤300ms 等)是
|
||
**待验证合同**。区分两个计数:**接纳的 run 数**(进入队列)与**执行许可**
|
||
(同时真正执行,含子代理、初始全局 20、每用户 2、索引 4);等待子代理/HITL 的
|
||
父 run 让出执行许可、保留会话所有权。压测在 U7 执行并绑定组件 SHA 出证。
|
||
|
||
## 5. 隔离测试库/目录/端口方案
|
||
|
||
| 资源 | 约定 | 生命周期 |
|
||
|---|---|---|
|
||
| 本机 PG 实例 | `scripts/svc.sh db create collabtest --port 8897 --tag test` | svc.sh 管理;用毕 `svc.sh collabtest stop` + `rm --purge` |
|
||
| 测试库/扩展 | 库 `agent_test`;`pg_trgm` 预装 public | 测试辅助幂等预装;CI 启动步显式预装 |
|
||
| 用例 schema | `t_*` / `pgbus_*` 前缀,随机名 | 每用例建、Cleanup 级联删 |
|
||
| 本机 Redis | `redis-server --port 6399 --save '' --appendonly no` | 纯内存、用毕即停 |
|
||
| CI | job `test-pg`:apt 安装 PG16+pgvector+Redis,端口 5432/6399 | 每次 PR 必跑;缺服务失败不跳过 |
|
||
|
||
本地跑真实库门禁:
|
||
|
||
```bash
|
||
export AGENT_PG_TEST_DSN="$(scripts/svc.sh db dsn collabtest --db agent_test --reveal | tail -1)"
|
||
export AGENT_REDIS_TEST_ADDR=127.0.0.1:6399
|
||
make test-backend-pg
|
||
```
|
||
|
||
禁止对共享/现役实例(如 `runtime/dev` 的库)跑测试;DSN 不入命令历史与任务卡。
|
||
|
||
## 6. KTD14 副本保护与保留合同
|
||
|
||
- 备份/导出/WAL/测试副本使用专用数据库角色(非应用角色),存放于受限目录
|
||
(0700,非工作区);传输与静态备份加密,解密材料存独立受管秘密存储。
|
||
- 保留期限:迁移演练副本用毕即删,最长 7 天;正式备份保留 30 天滚动 +
|
||
每月 1 份年度副本(待正式实例指定后确认)。
|
||
- 日志/报告只留统计与哈希:不落 DSN、密钥、文档正文;测试一律用脱敏数据。
|
||
- 恢复演练:每次演练恢复到新目标并核对应用可用与权限/文件完整性;
|
||
「备份命令成功」不等于可恢复。
|
||
- 阻塞项:正式导出前,未知 owner 的数据、未定位的权威文件、缺失的保留期限
|
||
任一存在即阻塞(不静默继续)。
|
||
|
||
## 7. 暂态 Worker 文件分类
|
||
|
||
| 类 | 内容 | 处置 |
|
||
|---|---|---|
|
||
| 可重建 | 构建产物 `bin/`、`node_modules/`、测试数据目录、`__pycache__` | 随时删除重建 |
|
||
| 必须迁移 | SQLite 库、`artifacts/` 工件、`.agentx/checkpoints.jsonl`、Squad FileStore/续跑标记 | U4 迁移 + 联合备份;U5 前禁止跨机接管 |
|
||
| 只读参考 | svc.env(600)、history.jsonl | 保留在实例目录,不入副本外流 |
|
||
|
||
## 8. 已知边界(诚实清单)
|
||
|
||
- CLI 子命令(apikey/user 等)不校验 tier;team 档语义只在 `serve` 入口强制。
|
||
- 迁移仍随启动执行(已原子 + 锁化);完全独立的 migrator 入口留待 U4 工具。
|
||
- 多实例安全**未**因此声明(R4/U5);本档只交付单实例 team 档与真库门禁。
|
||
- pgvector 扩展已安装 ≠ 启用;向量检索仍是应用内扫描(U6)。
|
||
|
||
## 9. 执行预算与动作授权(U3 切片 2 已实施)
|
||
|
||
### 执行许可(admission,R8)
|
||
|
||
- 设置键:`runtime.execBudgetGlobal`(全局并发执行上限,含子代理;0=不限,
|
||
默认)、`runtime.execBudgetPerUser`(每租户上限;0=不限)、
|
||
`runtime.execQueueMax`(待执行队列上限,默认 200)。数值为容量合同初值,
|
||
U7 压测后调整。
|
||
- 语义:会话回合与子代理同池计数;账本在数据库(`admission_leases`,PG 咨询
|
||
锁下原子清点),多实例天然共享;队列满时 API 在落库前 429(不写数据);
|
||
父 run 同步等待子代理或等待 HITL 时让出执行许可、保留会话所有权,恢复
|
||
执行重新获取——额度占尽时父子不互等。
|
||
- 接纳与执行分别计数:队列深度(接纳)与活跃租约(执行)是两个量,
|
||
诊断分别看 `Manager.QueueDepth()` 与 `store.ActiveExecutionSlots()`。
|
||
|
||
### KTD13 动作授权矩阵与公开契约兼容计划
|
||
|
||
矩阵(宿主侧 `server.ProjectAction`):
|
||
|
||
| 动作 | 语义 | 未注册 action-aware 时 |
|
||
|---|---|---|
|
||
| read | 读取项目资源(会话/消息/检索/下载) | 回落旧 EXT-8 只读适配器(兼容现网) |
|
||
| edit | 写入与修改 | **默认拒绝** |
|
||
| approve | 审批(HITL/命令确认) | **默认拒绝** |
|
||
| execute | 触发执行 | **默认拒绝** |
|
||
| admin | 管理 | **默认拒绝** |
|
||
|
||
规则:action-aware 适配器(组合根注入 `SetProjectActionAuthorizer`)注册后
|
||
对全部动作权威、出错 fail-closed;旧只读适配器不得自动获得写入能力。
|
||
|
||
**公开契约兼容计划**(后续版本落地):以版本化扩展把动作级判定并入
|
||
EXT-8 的 `ProjectAuthz` 公开契约(新增 action 参数的变体接口 + 契约版本号),
|
||
下游适配器按动作逐一声明能力;未声明动作保持默认拒绝,与宿主侧矩阵同语义。
|
||
旧 bool 契约在该版本内继续可用(映射为仅 read);Core/Host 与下游适配器
|
||
(RDM 的 ProjectAuthz 实现)一起验收,不另建成员权威。
|
||
|
||
## 10. SQLite → PostgreSQL 切换与恢复演练(U4 已实施)
|
||
|
||
工具:`make build` 产出 `bin/storage-migrate`(受管迁移入口;只处理 Backend 库,
|
||
不执行 SQLite dump 作为 PG SQL)。三个子命令:
|
||
|
||
```bash
|
||
# 1) 只读盘点:schema 版本、完整性、逐表计数、工件清单与哈希(§6.1)
|
||
storage-migrate inventory --source runtime/dev/data/agent-system.db \
|
||
--artifacts runtime/dev/data/artifacts --out inv.json
|
||
|
||
# 2) 一致性快照:VACUUM INTO(在线安全含 WAL)+ 可打开校验 + 逐表计数对账(§6.2)
|
||
storage-migrate backup --source runtime/dev/data/agent-system.db --out snap.db
|
||
|
||
# 3) 受管迁移:目标建 schema/扩展后按行复制;身份登记 + 逐表校验和 + 终验(§6.3)
|
||
storage-migrate migrate --source snap.db --target "$DSN" \
|
||
--migration-id <名> --artifacts runtime/dev/data/artifacts --out report.json
|
||
```
|
||
|
||
迁移身份与续传:`migration_id + source_snapshot_id(快照 SHA-256)+
|
||
source_schema_version` 登记在目标 `migration_control`;**仅同一冻结快照可续传**
|
||
(换快照/换身份均拒绝);目标业务表已有数据而身份为空即拒绝(不覆盖)。
|
||
|
||
校验与报告:逐表源/目标计数与主键序哈希链校验和(布尔列按目标 schema 对称
|
||
归一);复制后推进 SERIAL 序列;未知 owner(users 之外,''/'local' 单租户默认
|
||
除外)阻塞迁移;报告只含计数/校验和/清单哈希——无 DSN、密钥与行正文(KTD14)。
|
||
类型映射以目标 schema 为准(SQLite 0/1→BOOLEAN、BLOB→BYTEA、生成列不迁、
|
||
FTS5 影子表不迁——PG 侧生成列与索引自动重建);`admission_leases` 为运行态
|
||
不随迁。
|
||
|
||
### 切换顺序(正式窗口须另行授权;当前仅隔离演练已验证)
|
||
|
||
1. 固定源制品与路径,`inventory` 盘点;指定迁移 owner、窗口、回退判据。
|
||
2. `backup` 冻结快照(活跃 WAL 库不得只拷 `.db` 文件)。
|
||
3. 预演:独立测试目标 PG 上 `migrate`,核对报告全绿;预演库不作为正式目标。
|
||
4. 正式窗口:停新写 → 等待/收口在途 run(未知副作用记 recovery hold)→
|
||
停旧写者 → 终快照 → 空正式目标 `migrate` → 报告全绿。
|
||
5. 单入口切 team 档冒烟(登录/项目/会话/审批/检索/下载);fail-closed 不回 SQLite。
|
||
6. **PG 接受新写入前**可撤回;**之后**禁直切回旧 SQLite(向前修复或专项回迁)。
|
||
|
||
备份基线(正式目标启用后):pg_dump 逻辑备份 + pg_basebackup 物理基础备份与
|
||
WAL 归档/PITR;pg_dump 不能作 WAL 回放基础。每次演练恢复到新目标并核对。
|