From b360bcb9745e20d9d4f9f06c44a2936f47217ae4 Mon Sep 17 00:00:00 2001 From: weichen Date: Thu, 22 Oct 2026 09:11:10 +0000 Subject: [PATCH] Add container-storage initiative charter and reviewed plan Why: register the L1 initiative for the single-binary + containerized database/knowledge-storage overhaul (U1-U6) and land the reviewed plan as the charter's authoritative reference. Evidence: NOT_RUN (planning documents only; no product change) Impact: docs and task card only; no runtime behavior change. Refs: docs/superpowers/plans/2026-10-22-container-storage-plan.md --- .task/feature-container-storage-plan.md | 51 ++-- .../2026-10-22-container-storage-plan.md | 266 ++++++++++++++++++ 2 files changed, 301 insertions(+), 16 deletions(-) create mode 100644 docs/superpowers/plans/2026-10-22-container-storage-plan.md diff --git a/.task/feature-container-storage-plan.md b/.task/feature-container-storage-plan.md index e7ad5a3e..a58808ed 100644 --- a/.task/feature-container-storage-plan.md +++ b/.task/feature-container-storage-plan.md @@ -9,23 +9,42 @@ - 分支类型:initiative;initiative_id:feature-container-storage-plan;root_target:main;immediate_target:main;accepting_requirements:true - 需求分流:verdict=NEW;selected_initiative=无;requirement_sha256=53a3aac8b5638347861577e2ab6f487c182b364e44b1fb0b563df0fdb5834870;triage_receipt=/tmp/container-storage-plan-triage-20261022-b.json;receipt_sha256=31e6accb098e8572e3698e04e3dbafc340fd9ef300df7a09110f1cb249aabb44 -- 授权与交付终点:<本次允许的动作与终点;未授权事项写明> +- 授权与交付终点:按已审阅方案实施 U1—U6(M1—M3)并交付到 main;含各仓代码/测试/文档变更、PR/CI/合入。不含:生产迁移 O1、生产数据读取/写入、部署到生产、数据库大版本升级。 - 交付模式:goal-first(目标、范围和交付终点一次确认;范围内连续推进) - 实施执行:agent-per-unit(配置:AGENT-EXECUTION.md) - 合入执行:agent(已授权交付范围内,Review 通过、冲突解决且当前 HEAD 的 CI 通过后合入) - 人工决策点:仅限目标/范围/验收变更、重大取舍、高后果操作或无法自动判定的业务验收 -- 当前阶段:需求拆解;当前增量:I1(待定义) +- 当前阶段:实施与自检(M1/U1 起);当前增量:I1=U1 - 流程依据:仓库根目录 policy/delivery.md(归档后仍按仓库根目录定位) ## 目标与非目标 -<章程:用途与目标、接纳范围与非目标、方案/计划链接、分级测试策略、验收条件、追加领域规则、生命周期。> +### 章程(charter) + +**用途与目标**:按已审阅方案(`docs/superpowers/plans/2026-10-22-container-storage-plan.md`)把部署形态改造为:一个完整应用服务二进制、两个 PostgreSQL 容器(业务基座库 + RDM 领域库)、知识库 PostgreSQL/pgvector 容器(第三个逻辑库)、外置持久文件根;生产/测试/验证三套环境独立配置、数据、身份与凭据;形成可验证的完整备份恢复与环境克隆隔离流程(需求 R1—R8、决策 KTD1—KTD7 见方案)。 + +**接纳范围**:方案 Implementation Units U1—U6 及其测试;各仓仅做阻塞目标的最小接线。U1 环境与数据归属合同;U2 容器数据库与 svc 接线;U3 迁移与文件引用兼容;U4 组合备份与恢复新目标;U5 测试/验证克隆与环境选择;U6 单二进制与组合验收、运维交付。 + +**非目标**:生产迁移执行(方案 O1,另获窗口授权后单独安排);高可用平台、Kubernetes、托管云数据库、全量对象存储、应用微服务化;零停机/实时复制/PITR;删除既有 SQLite/原生 PG 路径;PG 大版本升级。 + +**分级测试策略**:L2→L1 用 `make test-affected` 最小直接检查;L1→main 最终窗口跑完整组合(`make test`,含 `test-pg`、`svc-realcombo`、`test-regulations-kb`);容器与文件恢复必须有真实临时环境验证,缺 DSN 的跳过不计通过。 + +**验收条件**:方案 Definition of Done——单二进制在目标环境启动并符合两容器三库边界;三环境独立可启停重建且隔离实测;完整备份恢复到新目录且原文/引用不变;真实迁移 fixture 对账通过;精确组件组合、测试证据、独立 Review、必需 CI 与规范文档齐备。 + +**追加领域规则**:manifest 是身份与期望态唯一权威,Compose 只作版本化模板(KTD3);普通启停/重建不隐式删卷、不隐式恢复旧备份、不在数据库失败时回退空 SQLite(R7);镜像按选定 digest/扩展版本逐项核对(KTD7);秘密不入仓不入日志(baseline 硬边界 2)。 + +**生命周期**:M1(U1→U2)→ M2(U3→U4)→ M3(U5→U6)→ M4 生产切换(O1 另行授权,不在本 initiative 内)。U1 完成后按实测数据规模细化后续工期;全部必需子任务合入后置 `accepting_requirements=false` 收口合入 main。 ## 子任务登记 | 子任务分支 | 必需 | 状态 | PR | |---|---|---|---| -| 待登记 | 否 | — | — | +| feature/container-storage-plan-u1 | 是 | 未开始 | — | +| feature/container-storage-plan-u2 | 是 | 未开始 | — | +| feature/container-storage-plan-u3 | 是 | 未开始 | — | +| feature/container-storage-plan-u4 | 是 | 未开始 | — | +| feature/container-storage-plan-u5 | 是 | 未开始 | — | +| feature/container-storage-plan-u6 | 是 | 未开始 | — | ## Agent 实施收据 @@ -37,31 +56,31 @@ ## 关联方向与规划 -- 适用状态:待核对(无适用规划时说明原因) -- 主记录路径/版本:待核对(路径按仓库根目录定位,归档后不变;只引用唯一正文) -- 对应里程碑:待核对 +- 适用状态:适用(本 initiative 的方案与实施计划) +- 主记录路径/版本:`docs/superpowers/plans/2026-10-22-container-storage-plan.md`(2026-10-22 审阅快照,含落库状态注记) +- 对应里程碑:M1(U1→U2)→ M2(U3→U4)→ M3(U5→U6);M4/O1 生产切换不在本 initiative ## 需求分析 | ID | 描述 | 项目符合度及依据 | 优先级 | 验收条件 | 依赖 | 结论 | |---|---|---|---|---|---|---| -| R1 | 待填写 | 待评估 | 待定 | 待定义 | 待确认 | 待评审 | +| R1—R8 | 见方案 Requirements 表(R1 单二进制、R2 容器化、R3 环境绑定、R4 恢复可核对、R5 迁移覆盖、R6 克隆隔离、R7 无隐式破坏、R8 操作记录) | 符合(方案已核对现有 svc/manifest/迁移器/KB Compose 能力) | 高 | 见方案各单元完成条件与 Definition of Done | U1←无;U2←U1;U3←U1/U2;U4←U2/U3;U5←U4;U6←U1—U5 | 纳入本增量(U1—U6) | ## 方案与计划 -- 方案引用:待填写(含对象版本) -- 实施计划引用:待填写(含增量与需求 ID) -- 测试计划引用:待填写(含需求 ID 与验收条件) +- 方案引用:`docs/superpowers/plans/2026-10-22-container-storage-plan.md`(2026-10-22 审阅快照;Product Contract、KTD1—KTD7、High-Level Technical Design) +- 实施计划引用:同上 Implementation Units U1—U6 与里程碑 M1—M3(M4/O1 不在本 initiative) +- 测试计划引用:同上 Verification Contract 与各单元测试文件/场景清单 ## 阶段记录 | 阶段 | 对象版本 | 状态 | 决策/执行者 | 时间 | 依据 | |---|---|---|---|---|---| -| 需求拆解 | 待定 | 待执行 | — | — | — | -| 需求评估 | 待定 | 待执行 | — | — | — | -| 需求表确认 | 待定 | 待执行 | — | — | — | -| 方案设计 | 待定 | 待执行 | — | — | — | -| 实施计划 | 待定 | 待执行 | — | — | — | +| 需求拆解 | 方案 Requirements R1—R8 | 已完成 | 主模型(方案会话)+ triage NEW | 2026-10-22 | /tmp/container-storage-plan-triage-20261022-b.json | +| 需求评估 | 方案 Problem Frame/边界假设 | 已完成 | 三视角文档审阅 + 主模型复核 | 2026-10-22 | /tmp/container-storage-plan-20261022/review.md | +| 需求表确认 | R1—R8 纳入 U1—U6 | 已完成 | 主模型 | 2026-10-22 | 方案 Requirements 表 | +| 方案设计 | KTD1—KTD7 | 已完成 | 方案会话(已审阅) | 2026-10-22 | plan.md | +| 实施计划 | U1—U6 + M1—M4 | 已完成 | 方案会话(已审阅) | 2026-10-22 | plan.md Implementation Units | | 实施与自检 | 待定 | 待执行 | — | — | — | | 正式测试与验收 | 待定 | 待执行 | — | — | — | | 代码 Review | 待定 | 待执行 | — | — | — | diff --git a/docs/superpowers/plans/2026-10-22-container-storage-plan.md b/docs/superpowers/plans/2026-10-22-container-storage-plan.md new file mode 100644 index 00000000..c5dfc591 --- /dev/null +++ b/docs/superpowers/plans/2026-10-22-container-storage-plan.md @@ -0,0 +1,266 @@ +--- +artifact_contract: ce-unified-plan/v1 +product_contract_source: ce-plan-bootstrap +execution: code +date: 2026-10-22 +title: 单一应用二进制与容器化数据库、知识库存储改造方案 +--- + +> **落库状态(2026-10-22)**:方案已获审阅并授权实施。任务以 L1 initiative +> `feature/container-storage-plan` 重新登记(R0=955a32de2bb49171348bad5f566cce935df19212)。 +> 原始规划工作区(基线 9a80897)因子模块物化失败已保留现场并对账后回收: +> 全部子模块 HEAD 均在远端分支上、无独有提交、无未跟踪文件,任务卡副本存于 +> `/tmp/container-storage-plan-20261022/card-auto-generated.md`。本文正文为审阅时快照, +> 其中基线 9a80897 与工作区失败描述属历史记录;实施以本卡与各子任务卡为准。 + +# 单一应用二进制与容器化数据库、知识库存储改造方案 + +本文是待用户审阅的方案与实施计划,不代表业务实施、部署或迁移授权。应用二进制及数据库容器的总体方向来自本次会话;具体分工、步骤与验收为本方案建议。 + +计划归属 Agent-System-Dev;本文因新工作区子模块物化失败暂存仓外,尚未提交或合入。路径以各标明仓库的根目录为基准。后续正规落点建议为 Dev `docs/superpowers/plans/2026-10-22-container-storage-plan.md`。 + +## Goal Capsule + +- **目标**:运维人员能重建生产、测试、验证环境,把一个完整环境迁到新机器或新目录,并通过恢复验证确认账号、项目、文档、文件和知识库引用仍可用。 +- **手段**:一个应用服务二进制,两个 PostgreSQL 容器,三套逻辑数据库,外置持久文件;同一制品使用独立环境配置(KTD1—KTD4)。 +- **当前授权**:制定方案和计划。产品代码、容器部署、生产数据读取/复制、迁移切换均未在本轮执行;后续按用户明确授权范围实施。 +- **执行责任**:各仓遵循自身 AGENTS;Dev 范围的可独立实施单元按 AGENT-EXECUTION.md 分配全新外部 Agent 会话,host 管理范围、验证、独立 Review 和交付。任务进度放任务卡,不在本文伪装已完成。 +- **停止条件**:需要新增数据库类型、改变业务权限、无法完整迁移现有数据、需要丢弃新写入或扩大业务范围时停止相关动作,提交最小决策;不为容器化引入高可用平台、通用运维平台或应用微服务化。 + +## Product Contract + +### Summary + +保留前后端、Agent、RDM、知识库接入在一个应用进程内;数据库依赖使用 Compose。业务 PostgreSQL 容器分别承载基座库和 RDM 领域库,知识库 PostgreSQL/pgvector 容器承载语料与检索索引。生产、测试、验证环境分别建立,不通过临时修改生产连接串来“切环境”。 + +### Problem Frame + +现有宿主数据库运维、应用快照、RDM 领域备份和知识库恢复各有入口,但尚未形成可核验的完整环境恢复闭环。容器化只改变数据库运行方式,必须同时处理身份绑定、数据库与文件的一致恢复点,以及复制环境后的副作用隔离。 + +### Requirements + +| ID | 要求与可核验结果 | +|---|---| +| R1 | 完整应用服务只需一个可执行文件,包含前端资源、后端、Agent、RDM、知识库接入;运行机无需源码、Go 或 Node 构建环境。 | +| R2 | 业务库和知识库存储容器化,明确持久卷、镜像版本、扩展版本及生命周期;容器重建后业务数据仍在。 | +| R3 | 每环境独立绑定基座库、RDM 库、知识库、文件根、实例身份、端口和凭据;错误绑定拒绝启动。 | +| R4 | 从备份恢复到新目录/主机后,账号、权限、业务记录、原文和历史引用可核对;成功备份必须是一个可解释的一致恢复点。 | +| R5 | 从当前实际 SQLite/宿主 PG 迁移时覆盖所有必需持久数据所有者,保留业务标识、引用与原始内容,缺失或未知数据阻止切换。 | +| R6 | 测试/验证克隆获得新实例身份及独立凭据,启动前隔离生产密钥、会话、自动任务和外部副作用;生产实例保持固定绑定。 | +| R7 | 普通启停、重建、升级不隐式删卷、不执行数据库大版本升级、不恢复旧备份、不在数据库失败时回退到空 SQLite。 | +| R8 | 形成可重复的组合验证和生产切换/回滚操作记录;实现完成、测试通过、生产迁移完成、业务验收通过分别记录。 | + +### 边界与假设 + +- “单一二进制”按用户原话“最终的服务”解释为一个常驻应用服务。允许部署配置、脚本和离线迁移工具存在;不新增常驻 admin、KB HTTP 或前端服务。本期不为统一离线工具而重构全部 CLI。 +- 一期面向单机部署,每套环境独立;可在同机不同端口运行,也可迁到不同主机。宿主应用通过回环地址连接本机容器。 +- 知识库容器化指语料数据库及向量索引容器化;检索编排、权限与引用业务仍在应用二进制内。原始文档使用外置持久存储。 +- 允许维护窗口,先实现可验证的停写备份与迁移,不承诺零停机、实时复制、PITR 或自动故障切换。 +- 保留既有 SQLite/原生 PG 运行路径用于兼容与受控回退;本方案目标环境使用容器 PG,不顺带删除旧实现。 +- 公有知识库共享、跨环境共用只读卷、Kubernetes、托管云数据库、全量对象存储替换均不进入首期。 +- 生产停写窗口、源实例、机器容量、实际源版本与数据规模在 U1 核实;它们不妨碍方案审阅,但未核实前不能安排生产切换。规划不承诺未经测量的 RTO/RPO。 + +## Planning Contract + +### 当前依据与可复用基础 + +本轮主仓基线 Dev `9a80897cb7e9108091d302e849f59662f21ce260`。以下是源码/文档核查,未探测实际生产实例,也未运行产品测试。 + +| 范围 | 已核对的依据 | 本次改造含义 | +|---|---|---| +| 单二进制 | Dev `Makefile`;Backend `web/embed.go`;RDM `main.go`、`scripts/build-product.sh` | 已有静态组合和前端嵌入,复用完整产品构建;不能用只有基座的二进制代替 RDM 产品。 | +| 宿主 PG | Dev `scripts/svc.sh` 的 pg_bindir/db_create/pg_do_start/pg_do_stop/pg_run/pg_dump_run/db_backup/db_restore/db_clone | 容器支持需要完整后端分派,不能只替换启动命令;备份恢复继续使用已有安全边界。 | +| 实例身份 | Dev `scripts/svc_manifest.py` 的 PROTECTED/db_anchor_of/reanchor;`tests/test_svc_identity.py` | manifest 已有权威身份;扩展三库和环境绑定,不另造第二份登记权威。 | +| 基座迁移 | Backend `cmd/storage-migrate/main.go` | 已有 SQLite→PG 工具,但只迁 Backend;artifacts 参数只盘点不复制,不能据此声称迁了整个产品。 | +| RDM 迁移 | RDM `main.go` 的 migrate-to-pg/migrate-check/backup-domain/restore-domain | 独立 RDM_DSN;RDM 领域库和 uploads 必须明确纳入。 | +| KB Compose | KB-Regulations `deploy/compose.yaml`、`deploy/README.md` | 已有本地 pgvector/pgvector:pg16、回环端口、卷与扩展初始化模板;固定项目名 kbreg 不适合作为所有环境的全局名称,已有标签不等于生产版本批准。 | +| 文件迁移 | Backend `internal/blobstore/blobstore.go`;KB-Regulations `migrations/0001_schema.sql`、`docs/operations/corpus-import.md` | 工件目录相关引用、source_assets.storage_uri 中 file 路径会影响异地恢复;不能只做 dump/restore。 | +| 组合恢复 | Dev `scripts/svc.sh` 的 agent_backup_snapshot;`tests/integration/regulations-kb/README.md` | 应用快照不含全套数据库和原始 manifest;KB 测试可复用,但不证明全套外部文件已恢复。 | + +RDM 研究对象为兄弟检出 `b14c84c6dcc945bd4d0a9ad446cf1ec980396491`,KB 为 `393555bec8d964f294f932616aa69ab833a06de1`;它们与 Dev `tests/integration/regulations-kb/components.pin` 的固定组合不同。本方案引用它们用于定位能力,正式实施前必须选定并验证精确组件组合,不能把研究检出当作已采纳版本。 + +已有恢复设计 `modules/documents/docs/proposals/2026-10-12-service-restart-data-recovery.md` 是设计约束来源,本文沿用其停写一致恢复点、恢复新目标、旧写者隔离思路,不把历史执行状态当现状。 + +### Key Technical Decisions + +**KTD1.应用保持单一服务二进制。** 复用现有产品组合构建,配置和数据外置;容器承载持久数据库依赖,知识库插件不拆进程。落实 R1/R2。(session-settled: user-directed — chosen over containerizing the whole application: user requires the final service to remain a single binary) + +**KTD2.两个 PG 容器、三个逻辑库。** 业务容器中分别设基座库与 RDM 库,知识库另用带 vector/pg_trgm 的 PG 容器。数据库使用独立应用角色;引导/迁移角色与应用权限分开,先核对现有启动迁移要求,再安排显式迁移阶段,不能直接收紧权限导致启动失败。落实 R2/R3/R5。 + +**KTD3.复用 svc 管理入口。** 新增窄的容器驱动和版本化环境配置,保留现有命令语义。manifest 是身份与期望态权威;Compose 文件是版本化模板,环境参数由同一配置解析生成。不得并存两份可独立修改的 DSN/卷权威。只管理明确归属本环境的容器,不启停外部数据库。落实 R3/R7。 + +**KTD4.稳定绝对数据根与环境独立资源。** 建议形态为 `state//` 与其外部 `backups//`,实际根由配置给出绝对路径;不相对代码 checkout/worktree 解析。Compose project、两套卷、各库、角色与端口都显式区分环境。凭据放受保护文件/secret 引用,日志和清单脱敏。文件树示意仅表达归属,不规定最终名称。 + +**KTD5.先备份完整恢复点,再追求不停机。** 关闭新写入口,排空或隔离在途任务,停止应用、定时任务、KB 导入/索引写者及迁移器;确认其他客户端不再写入后,对三库分别逻辑导出并复制受控文件。三次 dump 各自的快照不自动构成跨库一致性,靠整个窗口无写者保持一致。完成校验后才发布恢复包完成标记。落实 R4/R8。 + +**KTD6.恢复和克隆是不同操作。** 原实例恢复保留业务与实例身份,但须先停旧写者,绝不双开同一生产身份。测试克隆保留业务 ID 及引用关系,创建新的部署身份和守护绑定、数据库凭据;使生产登录会话/长期 API key 在副本失效,外部 provider 密钥不带入。后台任务与外发能力默认关闭,授权后逐项启用;不通过批量改业务 ID 实现隔离。落实 R3/R6。 + +**KTD7.迁移与升级分离。** 源 PG 采用同大版本兼容目标与匹配工具链,SQLite 迁移用已有逻辑迁移器;本次不顺带 PG 大版本升级或强制统一业务/KB PG 大版本。实施时固定经过验证的镜像 digest、平台与扩展版本。镜像官方文档说明不同主版本的 PGDATA/卷位置存在差异,配置按选定镜像逐项核对,不能把 KB pg16 的挂载路径盲用到另一主版本。初始化脚本仅负责新卷引导,既有库变更走显式迁移。落实 R2/R5/R7。 + +### High-Level Technical Design + +以下是关系和流程草图,新增配置/命令的最终命名由实现单元在既有接口中确定。 + +```mermaid +flowchart LR + Client[浏览器] --> App[一个完整应用二进制] + Profile[环境配置与实例 manifest] --> App + Profile --> Compose[Compose 数据依赖] + App --> Base[业务容器 / 基座库] + App --> RDM[业务容器 / RDM 领域库] + App --> KB[知识库容器 / 语料库与索引] + App --> Files[持久文件根 / 工件 uploads 原件] + Compose --> Base + Compose --> RDM + Compose --> KB +``` + +```text +state// + instance/ manifest 与受保护配置、应用版本引用 + files/ 工件、RDM uploads、KB 原件及必要解析产物 +Docker 持久卷:-business、-knowledge(各环境独立) +backups/// 三库导出、文件、配置恢复材料、版本与校验清单 +``` + +```mermaid +flowchart LR + A[识别目标与锁定操作] --> B[预检配置/身份/镜像/资源] + B --> C[启动两库容器] + C --> D[认证/扩展/schema/三库身份检查] + D --> E[按需执行显式迁移并核验] + E --> F[启动应用] + F --> G[业务就绪验证] + D -->|失败| H[拒绝启动并保留现场] +``` + +```mermaid +stateDiagram-v2 + [*] --> Running + Running --> Quiescing: 请求一致备份 + Quiescing --> Frozen: 写者已停且在途状态已记录 + Frozen --> Capturing: 三库与文件导出 + Capturing --> Verified: 完整性和清单校验 + Capturing --> Incomplete: 失败或中断 + Verified --> Running: 发布完成标记后恢复原实例 + Incomplete --> Running: 确认现场可安全恢复后解除停写 +``` + +恢复流程:读取完成清单 → 校验兼容版本与文件 hash → 选择空的新目标 → 建库/恢复角色权限及三库 → 还原文件与受控路径映射 → 核对实例模式(原实例/克隆)→ 禁止外部副作用下启动 → 登录、权限、文档、KB 引用验证 → 单独决定是否开放写入。任一步失败保持目标隔离,不覆盖旧系统。 + +### 完整恢复包合同 + +- 基座、RDM、KB 三库的逻辑导出及 schema/扩展版本;必需角色/权限用受控恢复定义记录,不能盲目导入生产全局超级用户。 +- 工件、uploads、KB 原件及必要解析产物;包含全部必需插件声明的数据。对对象存储记录不可变版本/校验值及可恢复获取方式;无法获取的必需对象阻止完整恢复声明。 +- 原始实例 manifest、部署配置、应用制品及插件/前端组合的 SHA、容器镜像 digest、平台信息;配置清单不含明文秘密,恢复秘密通过独立受保护介质或重新注入。仅含引用时必须验证引用在目标可解析,不能称恢复包独立可恢复。 +- 文件清单与 hash、数据所有者清单、停写时间和操作状态、恢复工具版本、校验结果及完成标记。备份与 runtime 卷分离,至少验证一份异机/独立存储副本可读取。 +- 原件路径变更仅调整定位信息,不改变内容 hash、语料修订、节点 ID、历史 excerpt 和审计封印。受保护审计内容若包含原路径,必须通过解析映射兼容,禁止重写封印记录。 +- 向量索引可重建,但 embedding 模型/维度和语料版本要记录;恢复测试不依赖付费重新嵌入,优先复用保存的向量重建索引。 + +## Implementation Units + +### U1.环境与数据归属合同 + +- **需求**:R1/R3/R5/R6,KTD1—KTD4。 +- **目标**:一份可解析配置确定完整实例资源,明确现有数据来源和迁移边界。 +- **主要文件**:Dev `scripts/svc_manifest.py`、`scripts/svc.sh`、`docs/svc.md`、`PROJECT.md`;新增环境 schema/示例置于 Dev `deploy/`(建议路径)。 +- **做法**:扩展现有 manifest 绑定基座/RDM/KB,版本化旧配置升级;保护环境命令不受调用者环境变量污染。列出各数据所有者、类型、源版本、目录、体量、表/对象清单、引用形式和唯一写者。不输出秘密或业务内容。生产盘点需先获得对应访问授权。 +- **测试文件**:扩展 `tests/test_svc_identity.py`、`tests/test_svc_lifecycle_isolation.py`、`tests/test_svc_precheck.py`。 +- **场景**:旧配置升级保留身份;错库/错根/foreign marker 拒绝;同名项目或冲突端口在修改前失败;在另一 checkout 调用仍定位同一资源;三库中任一必需绑定缺失不能静默新建空库。 +- **完成条件**:配置、归属清单和迁移范围有唯一解释;明确需迁移的每个数据所有者。依赖:无。 + +### U2.容器数据库与 svc 接线 + +- **需求**:R2/R3/R7,KTD2—KTD4/KTD7。依赖 U1。 +- **主要文件**:Dev `scripts/svc.sh`(后端分派)、新增 `scripts/svc_containers.sh` 和 `deploy/compose.storage.yaml`(建议路径);KB-Regulations `deploy/compose.yaml`、`deploy/initdb/01-extensions.sql`、`deploy/README.md` 作为复用来源,避免复制成两套互相漂移的模板。 +- **做法**:start/stop/status/SQL/dump/restore 覆盖同一容器驱动;记录明确所有权;卷重建、普通停止和数据销毁分别处理。应用仅连 loopback 发布端口。引导创建基座/RDM 独立库与角色,KB 创建扩展;后续变更使用显式迁移。启动顺序验证真实认证、扩展和身份,不能只依赖 pg_isready。 +- **测试文件**:新增 Dev `tests/test_svc_containers.py`;扩展 `tests/test_svc_precheck.py`、`tests/test_svc_realcombo.py`。 +- **场景**:prod/test/verify 同时运行互不冲突;停止/重建一套不影响其他套且不丢数据;缺 Docker/镜像/磁盘/凭据时在破坏性动作前失败;密码变更不误以为改 env 就改变已初始化库;容器意外停止时应用不得写入 SQLite。 +- **完成条件**:用固定制品及临时环境完成两容器三库启动、持久化、重建与失败路径验证。运行冒烟优先,不用大量模拟测试替代真实容器验证。 + +### U3.迁移与文件引用兼容 + +- **需求**:R4/R5/R7,KTD5—KTD7。依赖 U1/U2。 +- **主要文件**:Backend `cmd/storage-migrate/`、`internal/blobstore/blobstore.go`;RDM `main.go` 与其现有领域迁移实现;KB-Regulations 的 source_assets 读取/原件定位实现及 `docs/operations/corpus-import.md`。函数名在实施启动时定点核对,不另建并行迁移框架。 +- **做法**:基座和 RDM 分别复用现有迁移器;覆盖实际 schema 的新增表、外键、序列/标识和身份记录;未知表不能悄悄遗漏。已有 PG 走兼容逻辑恢复。文件迁移校验内容和所有权,新增受控资产根映射或兼容相对引用,维持旧引用可读取。禁止迁移时跨出允许根或追随外部软链复制未知文件。 +- **测试文件**:Backend `cmd/storage-migrate/main_test.go`、`integration_test.go`、`seeded_singletons_test.go` 与 `internal/blobstore/` 对应测试;RDM 现有领域迁移测试(实施前定位);KB-Regulations `tests/integration/recovery_pg_test.go`。 +- **场景**:SQLite 基座+RDM 迁入不同逻辑库;原 PG 同版本恢复;空库与真实结构 fixture;失败/重跑/非空目标拒绝;未知表拒绝;不同根目录恢复后读取旧工件与 file URI 原件;越界路径拒绝;历史 citation/审计 hash 不变。 +- **完成条件**:逐所有者对账,不仅比较行数,还核对 ID、关键引用、内容 hash、权限和新写入;不能完成的必需所有者阻止继续生产准备。 + +### U4.组合备份与恢复新目标 + +- **需求**:R4/R5/R8,KTD5/KTD7。依赖 U2/U3。 +- **主要文件**:Dev `scripts/svc.sh` 的 backup/restore 入口;新增组合恢复辅助实现(建议 `scripts/svc_bundle.py`);`docs/svc.md`、恢复操作说明;各组件只提供必要导出/校验接口。 +- **做法**:按恢复包合同采集全部数据,锁定同环境操作,停写并确认所有写者;失败包无完成标记。完整备份默认只恢复到空的新目标;应用制品和 schema 兼容预检先于开放写入。秘密处理有明确备份/重新注入路径及权限校验。 +- **测试文件**:扩展 `tests/test_svc_backup.py`;新增 `tests/test_svc_bundle.py`;扩展 `tests/ops/run_backup_drill.sh` 的不同目标根场景。 +- **场景**:三库与文件可恢复;备份中断、空间不足、错包、hash 损坏、缺原件、缺必要 secret、镜像不兼容拒绝;目标非空拒绝;不得覆盖生产;重新启动源实例不把未完成包发布为成功;保留原生产身份恢复时,目标接管前必须隔离旧写者;独立克隆从已完成的一致备份恢复,源实例可在备份完成后继续运行,但目标首次启动前必须完成新身份、独立凭据及副作用隔离。 +- **完成条件**:干净环境恢复完整产品并生成可复核清单;实测备份大小、停写时长和恢复用时。 + +### U5.测试/验证克隆与环境选择 + +- **需求**:R3/R6/R8,KTD4/KTD6。依赖 U4。 +- **主要文件**:Dev `scripts/svc.sh` 的 clone/启动接线、`scripts/svc_manifest.py`;Backend/RDM 现有身份、会话和任务控制入口仅作必要接线;测试数据 fixture 与说明。 +- **做法**:以明确目标环境创建新实例。业务 ID 不改,部署身份、守护与凭据换新;登录会话/API key 不在副本继续有效,账号密码处理按克隆用途明确。需要复制生产敏感数据时先落实访问范围和脱敏策略;常规自动验收优先合成数据。外部密钥、自动调度与恢复任务副作用默认禁用,并在首次启动前生效。 +- **测试文件**:扩展 `tests/test_svc_identity.py`、`tests/test_svc_lifecycle_isolation.py`;新增 `tests/test_svc_environment_clone.py`。 +- **场景**:克隆后生产仍正常;新身份不触发原守护冲突;旧 token 无法访问副本;待执行任务不自动发信/调用真实 provider/写生产目录;选择 test 不修改 prod 配置;操作摘要明确目标环境。 +- **完成条件**:三套环境同机并存,隔离由实际读写与副作用拒绝验证,不靠名称或配置声明。 + +### U6.单二进制与组合验收、运维交付 + +- **需求**:R1—R8,KTD1—KTD7。依赖 U1—U5。 +- **主要文件**:Dev `Makefile`、`tests/test_svc_realcombo.py`、`tests/integration/regulations-kb/run.sh`、`components.pin`、`PROJECT.md`、`docs/svc.md`;RDM `scripts/build-product.sh`;各仓必要 runbook/组合指针。 +- **做法**:固定完整产品与镜像组合,在没有源码及 Go/Node 的机器/隔离环境用同一应用制品启动。把恢复、克隆、数据库容器重启加入组合验证。必要管理操作优先复用同一产品已有入口,离线工具不成为常驻依赖。受影响仓独立验证后再推进 Dev 组合,不重做发布体系。 +- **场景**:UI/API、正常账号登录、角色边界、项目/会话、RDM 上传/文档原件读取、知识库检索、历史引用解析;两库容器依次重启;新目录恢复;test/verify 重建不影响 prod;客户端制品无 secret。 +- **完成条件**:满足 Definition of Done;输出生产切换操作单与回滚分界,实测停写时间供用户安排窗口。生产执行属于下面 O1,不由代码测试替代。 + +## Verification Contract + +- 本轮是规划:产品测试、真实容器试验、迁移演练、生产盘点/部署均为 **NOT_RUN**;源码核查属于 SELF,不能提升为 GATE 或 REPLAY。 +- 实施每单元先运行其最小直接检查,容器与文件恢复必须有真实临时环境验证。禁止把缺 DSN 导致的跳过计作通过;真实测试仅指向显式临时环境。 +- Backend 真 PG 迁移测试使用 `AGENT_PG_TEST_DSN`;法规组合门禁使用 `KBREG_TEST_DATABASE_URL`、精确 RDM/KB pin 及既有 `make test-regulations-kb`。 +- Dev 治理脚本确有修改时运行 `make test-governance`;最终组合按项目要求执行 `make test`,并以当前 CI 要求核对 `test-pg`、`svc-realcombo` 等检查,不能凭旧清单声称全部通过。 +- 推进 Dev gitlink 前完成所需组合验证;命令原始输出经 `make evidence` 写任务卡。正式 Review 前重放最小集合、同步权威目标;合入信任来自精确 HEAD 的必需 CI 或独立 REPLAY。 +- 全量检查只在最终候选或有必要时运行;发现无关非阻塞问题不扩大本次任务。 + +## O1.生产迁移与回滚计划(另行授权执行) + +1. **确认源与窗口**:记录实际源实例、三库/文件清单、schema、版本、容量、现有身份、备份位置及授权范围;确认恢复演练达标和可接受停写时间。 +2. **提前准备目标**:拉取固定镜像、准备空库/角色/持久目录、验证磁盘与网络;用演练副本验证完整应用制品。此阶段不改生产连接。 +3. **冻结生产写入**:暂停入口及所有后台/外部写者,排空或隔离在途工作,确认旧实例不会被 supervisor 自动拉起;记录已确认写入的对账点。 +4. **最终备份与迁移**:按 U3/U4 生成最终完整包并恢复目标;核对所有必需数据与文件,运行只读业务验证;保持外部副作用关闭。 +5. **受控切换**:以迁移操作更新目标绑定、身份和文件路径;先验证登录/权限/文档/知识库,再开放写入及经确认的后台任务。避免两个生产写者同时存在。 +6. **观察与保留**:保留旧数据及最终备份,只读保护并记录新系统写入开始时间;到达业务验收及约定保留期后才单独安排旧资源回收。 + +回滚分界必须写入操作单: + +- **新目标尚无业务写入**:停止新实例,确认无新数据后恢复旧配置/旧写者;不可让双方同时写。 +- **新目标已有业务写入**:停止写入并保存新数据,禁止简单切回旧库;评估向前修复或经过验证的数据对账/回迁。未经确认不丢弃新写入。 +- **schema 已改变**:旧应用制品不一定兼容。代码回滚、数据库恢复和业务数据回迁分别验证,不能用“换回旧二进制”代替恢复方案。 + +## Definition of Done + +代码交付完成须同时满足: + +- 一个完整应用服务二进制在目标运行环境启动,业务/RDM/KB 数据存储符合两容器三逻辑库边界。 +- prod/test/verify 可独立启动、停止、重建与选择,配置/数据/身份/权限隔离已验证。 +- 完整备份可以恢复到不同根目录;原文可读、业务引用和历史法规引用不变;缺失数据时明确失败。 +- 真实迁移 fixture 对账通过,重启与容器重建不丢数据,失败不会回退空系统或启动外部副作用。 +- 精确组件组合、测试证据、独立 Review、所需 CI 及规范文档齐全;没有遗留试验实现进入最终 diff。 +- O1 的执行另记:代码完成不等于生产迁移完成,恢复演练也不等于业务验收。 + +## 顺序与建议里程碑 + +| 里程碑 | 工作 | 出口 | +|---|---|---| +| M1 最小可运行 | U1 → U2 | 同一应用连接两容器三库,test/verify 并存,持久化与错误绑定验证通过 | +| M2 可迁移可恢复 | U3 → U4 | 完整数据恢复到新目录,原文和历史引用可核对 | +| M3 可安全切环境 | U5 → U6 | 克隆隔离、完整产品组合验证、操作说明齐备 | +| M4 生产落地 | O1 | 获得窗口授权后迁移、业务验收,旧数据按约定保留 | + +U1 完成后再按实际 schema 覆盖、文件规模及演练用时细化工期;当前不把未测量的数据量换算为承诺日期。每个里程碑只处理阻塞目标的问题。 + +## 外部依据与待核验项 + +本轮尝试读取 Docker Compose、PostgreSQL 备份与 pgvector 官方文档;网络读取不完整。成功获取 Docker Official Image 的 PostgreSQL 说明(docker-library/docs 的 postgres/README.md),其中确认 PGDATA/卷位置随主版本变化、初始化参数仅对新数据目录生效、密码支持文件注入。这些仅作为镜像适配约束,未确定最终镜像 digest,也未验证某个部署平台。 + +实施 U2 前需针对所选精确版本再次核对 Compose/镜像/pgvector 官方资料,并做真实冒烟;失败则阻止该镜像采用,不阻止本方案的源码设计工作。