diff --git a/.doc/ops/short-term/2026-09-24-single-binary-deploy-design.md b/.doc/ops/short-term/2026-09-24-single-binary-deploy-design.md new file mode 100644 index 00000000..a7e88fa2 --- /dev/null +++ b/.doc/ops/short-term/2026-09-24-single-binary-deploy-design.md @@ -0,0 +1,76 @@ +--- +title: "非容器化单二进制三环境交付方案(设计)" +task_id: "single-binary-noncontainer-design-2026-09-24" +status: in_progress +created: 2026-09-24 +updated: 2026-09-24 +owner: Cursor +task_type: research +task_tier: small +policy_revision: "AGENTS+CURRENT@edbe59247872ef5861bafd30068955e22288c6ff" +branch: feature/single-binary-deploy-design-2026-09-24 +worktree: .worktrees/single-binary-deploy-design-2026-09-24 +base_dev_sha: "edbe59247872ef5861bafd30068955e22288c6ff" +write_scope: + - ".doc/system-design/2026-09-24-single-binary-non-containerized-deployment.md" + - ".doc/ops/short-term/2026-09-24-single-binary-deploy-design.md" + - ".doc/ops/CURRENT.md" +allowed_environments: [] +mutex: "single-binary-deploy-design" +review_state: pending +integration_state: pending +deployment: not_required +cleanup: pending +cleanup_owner: 独立维护者 +cleanup_trigger: 设计评审通过或任务 cancelled/done 后按门禁复查 +remote_sync: not_requested +catalog_requirement: R-single-binary-non-container-deploy +--- + +# 非容器化单二进制三环境交付方案(设计) + +## 用户目标与授权 + +- 用户目标:制定本项目非容器化方案,尽可能单二进制交付;完善时须覆盖开发测试、内部测试、生产上线三类部署。 +- 已确认决策:纯单文件 server;PG 为 `managed`(dev)/`attach`(main)分级;PI runner 外置 sidecar。 +- 交付终点:可审设计文档落盘(非实施)。 +- 禁止:未授权 push、晋升 test/main、改 gap-matrix / FEATURE-MATRIX 冒充发布、业务环境写操作。 + +## 范围与非目标 + +- 允许写入:上表 write_scope(文件级,规避与 `member-permissions-doc` 占用整树 `.doc` 的硬 scope 冲突)。 +- 主设计:[../../system-design/2026-09-24-single-binary-non-containerized-deployment.md](../../system-design/2026-09-24-single-binary-non-containerized-deployment.md) +- 非目标:P1–P7 代码实施;system-design/README 索引更新(该文件正被并行任务修改,留给收口或后续 docs 任务)。 + +## 相关问题与经验 + +- catalog search「单二进制/非容器化」:无既有 R-ID 命中;已登记 `R-single-binary-non-container-deploy`。 +- 硬重叠:`member-permissions-doc-2026-09-24` scopes=`['.doc']` 与本任务路径前缀冲突;文件不重叠,以文件级 scope 注册规避 register 门禁;实施期建议对方收窄 scope。 +- 清理:关闭已合入但仍 `active` 且 scopes=`['.']` 的 `integrate-governance-console-p1-2026-09-24`、`integrate-gc-p1-closeout-2026-09-24`(queue 已 completed,merge 已在 local_dev)。 + +## 步骤与验收 + +1. [x] 建 worktree / 注册 / CURRENT 认领 / catalog 需求 +2. [x] 撰写三环境方案文档 +3. [x] 一致性自查(PROJECT 端口/验证契约/红线) +4. [ ] lease_run 提交 `docs(design)`;不申请集成(先评审) + +验证:纯文档 — diff、相对链接、拓扑与门禁叙述一致;**NOT REQUIRED** 产品 PI / 全量 Go(依据验证契约「纯规范/普通文档」)。 + +## 验证与证据 + +| 范围 / 被测 SHA | 命令与环境 | 预期 | 实际 / 判定 | 证据 | +|---|---|---|---|---| +| 设计文档 | 对照 PROJECT 端口表与 compose;相对链接解析;validateProductionSecrets / FAV 红线 | 一致 | PASS:8080/8081/8000、5433/5434/5435、PI 18865–67、data/{dev,test,main} 对齐;链接已修;main 密钥与 ALLOW_IN_MEMORY/FAV 叙述对齐 | 主设计 §2/§4.3;config.go validateProductionSecrets | + +## 收口与交接 + +- 评审通过后:另开 **implementation** 任务执行 P1+;本任务可 `done`。 +- 不默认 queue enqueue。 +- review_state / integration_state 以工具收据为准更新。 + +## 相关链接 + +- 主设计:`.doc/system-design/2026-09-24-single-binary-non-containerized-deployment.md` +- Plan:用户确认的「非容器化单二进制三环境交付方案」 +- Catalog:`R-single-binary-non-container-deploy` diff --git a/.doc/system-design/2026-09-24-single-binary-non-containerized-deployment.md b/.doc/system-design/2026-09-24-single-binary-non-containerized-deployment.md new file mode 100644 index 00000000..b2d421e9 --- /dev/null +++ b/.doc/system-design/2026-09-24-single-binary-non-containerized-deployment.md @@ -0,0 +1,304 @@ +# 非容器化单二进制交付方案(dev / test / main) + +| 字段 | 值 | +|---|---| +| status | proposed(设计评审;未授权实施) | +| task_id | single-binary-noncontainer-design-2026-09-24 | +| owner | Cursor | +| created | 2026-09-24 | +| catalog | R-single-binary-non-container-deploy | +| base_dev_sha | edbe59247872ef5861bafd30068955e22288c6ff | +| 授权 | 用户确认「纯单文件 server + server 自管 PG(managed)」;本文件仅为设计产物,不含业务实施/环境写操作 | + +> 相关入口:[PROJECT.md](../../PROJECT.md) 环境拓扑 · [验证契约](../ops/2026-09-21-validation-contract.md) · [gap-matrix](../remediation/gap-matrix.md) · 任务 [../ops/short-term/2026-09-24-single-binary-deploy-design.md](../ops/short-term/2026-09-24-single-binary-deploy-design.md) + +--- + +## 1. 目标与非目标 + +### 1.1 目标 + +1. **单一 Go 二进制交付** `agent-server`:内嵌前端 `web/dist`、工作流模板、agent 指令配置、goose 迁移;进程内合并 `cmd/events` 消费者。 +2. **非容器化运行**:目标机不依赖 Docker Compose;PostgreSQL + pgvector 由本机安装,PI Agent Runner 以外置 sidecar 目录交付。 +3. **覆盖三环境**:开发测试(dev)、内部测试(test)、生产上线(main),端口/数据隔离/密钥/模型 pin/晋升门禁与现拓扑语义对齐。 +4. **渐进可回退**:`LOCALPG_MODE=off` 保留现有容器 DSN 语义;compose 路径在过渡期并存。 + +### 1.2 非目标(本设计明确不做) + +- 把 Node/`pi-coding-agent`/pgvector `.so` 打进同一个可执行文件(全家桶)。 +- 用 SQLite 重写业务库与向量检索层(`<=>` 硬依赖 pgvector)。 +- 生产多机 HA / 自动故障转移(与现状单机 compose 等价,不降级也不夸大)。 +- 未经单独授权的 main 晋升、远端 push、gap-matrix 放宽。 +- 变更 FEATURE-MATRIX 完成度(纯设计文档)。 + +### 1.3 决策摘要(已确认) + +| 决策点 | 选择 | +|---|---| +| 交付边界 | 纯单文件 server;PI runner 外置 sidecar | +| PG 托管 | `LOCALPG_MODE=managed\|attach\|off`;dev 默认 managed;main 默认 attach;test 可选 | +| 共享 KB | test/main 仍可连运维共享实例;dev managed 可在同实例建第二 database | + +--- + +## 2. 现状依据 + +### 2.1 三环境拓扑差异 + +| 维度 | dev (`agent-dev`) | test (`agent-test`) | main (`agent-main`) | +|---|---|---|---| +| HTTP / 业务 DB / PI / events | 8080 / 5433 / 18865 / 8088 | 8081 / 5434 / 18866 / 8089 | 8000 / 5435 / 18867 / 8090 | +| 数据根 | `./data/dev` | `./data/test` | `./data/main` | +| 实际运行 | compose 跑 system-db+pi-agent;`launch.sh` 排除 app,宿主 `bin/server` + Vite :3100 | 全容器,镜像 `*:test` | 全容器,`restart: always`;app `depends_on: events healthy` | +| 模型 | MiniMax-M2.7-highspeed | MiniMax-M3(release pin) | MiniMax-M3 | +| 密钥 | 默认可缺省 | DB/ADMIN `:?required` | DB/ADMIN/RUNNER_TOKEN/KB `:?required`;`AUTH_REGISTRATION_ENABLED=false` | +| DB init 挂载 | `context_init.sql` | `extensions_init.sql` | `00001_baseline.sql` | +| 晋升 | — | rc tag + promotion-receipt | release tag(`release-to-main.sh`) | +| 共享 KB | 三环境共用 `shuimu-kb-shared:5432` / `regulations` | 同左 | 同左 | + +### 2.2 代码事实(改造锚点) + +| 能力 | 现状 | 单二进制化路径 | +|---|---|---| +| Go 服务 | `CGO_ENABLED=0` 静态编译([`deploy/app/Dockerfile`](../../deploy/app/Dockerfile)) | 天然可交付静态二进制 | +| 前端静态资源 | [`internal/server/static_assets.go`](../../internal/server/static_assets.go) 纯磁盘候选路径 | `go:embed` +「磁盘优先 → embed 回退」 | +| 文档模板 | [`templates/embed.go`](../../templates/embed.go) 已嵌 `docs/*.md`;[`internal/template/loader.go`](../../internal/template/loader.go) embed→磁盘双通道 | 扩展 configs embed;沿用双通道 | +| goose 迁移 | [`internal/db/migrate.go`](../../internal/db/migrate.go) 磁盘目录;goose v3 支持 `SetBaseFS` | embed.FS + 可选磁盘覆盖 | +| events | [`cmd/events`](../../cmd/events) 独立二进制 :8088/8089/8090 | 抽为 internal,server 内 goroutine;cmd 保留过渡 | +| PI runner | Node 22 容器 + `pi-coding-agent@0.85.1` + `deploy/pi-agent/*.mjs`;HTTP `PI_AGENT_RUNNER_URL`;另有 `PiAgentBin` CLI 回退 | 外置 sidecar;不进 Go 二进制 | +| 向量检索 | [`internal/kb/retrieve.go`](../../internal/kb/retrieve.go) 使用 `<=>` | 继续依赖本机 pgvector | +| 生产密钥门禁 | [`validateProductionSecrets`](../../internal/config/config.go)(ENV=main) | 保留,并由 preflight/EnvironmentFile 等价落地 | + +--- + +## 3. 目标架构 + +```mermaid +flowchart TD + subgraph bundle["交付物 agent-server-VER-linux-amd64.tar.gz"] + BIN["agent-server 单二进制
embed: web/dist + configs + goose
in-process: events 消费者"] + SIDE["pi-runner-sidecar/
node_modules + *.mjs + start.sh"] + UNIT["systemd 单元模板 ×3 环境"] + PREF["preflight.sh"] + end + BIN -->|"dev: managed"| PGD["localpg 子进程
unix socket
PGDATA=DATA_DIR/pg"] + BIN -->|"test: managed 或 attach"| PGT["本机原生 PG 实例"] + BIN -->|"main: attach"| PGM["独立 systemd postgresql@16
崩溃隔离 / 独立备份"] + BIN -->|"PI_AGENT_RUNNER_URL"| NODE["node22 sidecar"] + PGM -.->|"POSTGRES_SHARED_KB_DSN"| KB["共享 KB PG regulations"] +``` + +### 3.1 PG 托管三级(`internal/localpg`) + +环境变量 `LOCALPG_MODE`: + +| 模式 | 行为 | 默认环境 | +|---|---|---| +| `managed` | 发现 `pg_ctl`/`initdb` → `initdb`(若 `PGDATA` 空)→ 拉起 postmaster(unix socket,可选 TCP 绑定环境端口)→ `createdb` + `CREATE EXTENSION vector` → 复用 `RunMigrations`;SIGTERM 逆序停库 | **dev** | +| `attach` | 不启停 postmaster;仅连接 `APP_DB_DSN` + 启动迁移;缺库/缺扩展由 preflight 拒绝 | **main**;test 可选 | +| `off` | 现状语义:完全依赖外部 DSN(含 Docker 网络主机名) | 过渡期 / 兼容 compose | + +统一 bootstrap 覆盖今日 compose 三套 init SQL 差异:扩展创建 + 基线迁移由 goose 链承担,不再按环境挂不同 `docker-entrypoint-initdb.d` 文件。 + +共享 KB: + +- **dev + managed**:同实例第二 database `regulations`(或 `KB_DB_NAME`),DSN 指向本地 socket。 +- **test / main**:`POSTGRES_SHARED_KB_DSN` 指向运维管理的共享实例(保持「知识库共享、业务库隔离」)。 + +### 3.2 资产嵌入与解析优先级 + +| 资产 | 包建议 | 运行时解析 | +|---|---|---| +| `web/dist`(含 `.br`/`.gz`) | `web/embed.go` → `embed.FS` | **DATA_DIR 或 cwd 磁盘优先** → embed 回退(dev Vite/热更不破坏) | +| `configs/agents|shared|overlays` | `configs/embed.go` | 同 loader 双通道:embed 优先或磁盘覆盖(与现模板策略对齐后统一文档) | +| `deploy/postgres/goose/*.sql` | `goose/embed.go` + `goose.SetBaseFS` | 磁盘目录存在则优先(运维补丁);否则 embed | +| `templates/docs` | 已存在 | 保持 | + +静态服务保留现有 Accept-Encoding 协商(br > gzip);embed 变体通过 `fs.FS` + `http.FileServer`/`ServeContent` 可读实现(需 `io.ReadSeeker`;可用字节缓冲包装)。 + +### 3.3 events 合并 + +- 将 `cmd/events` 消费循环抽到 `internal/app/eventsconsumer`(或等价包),由 `cmd/server` 启动时按 `EVENTS_INPROCESS=true`(默认 true)拉起。 +- `/api/v1/ready`:迁移完成 **且** 消费者就绪后才放行(替代 main compose 中 `app depends_on events healthy`)。 +- `cmd/events` 独立入口保留至少一个大版本,便于灰度与排障;端口语义在 in-process 模式下不再对外暴露(或仅 loopback 诊断)。 + +### 3.4 PI runner sidecar + +目录布局(示意): + +```text +pi-runner-sidecar/ + start.sh # 自 entrypoint.sh 移植:写 models.json / settings.json + runner.mjs, pi-args.mjs, result-v1.mjs, settle-policy.mjs, ... + extensions/ + package/ # 或预装 node_modules(含 @earendil-works/pi-coding-agent@钉扎版本) +``` + +- 绑定 `DATA_DIR/workspaces`、`DATA_DIR/agent_sessions`。 +- server:`PI_AGENT_RUNNER_URL=http://127.0.0.1:` + `RUNNER_AUTH_TOKEN`(main 必填,与现校验一致)。 +- 可选回退:`PiAgentBin` + bridge(仅非产品验收路径;产品验收仍须真实 Runner HTTP)。 + +--- + +## 4. 三环境部署设计 + +### 4.1 dev — 开发测试 + +**目标**:去掉对本机 Docker 的硬依赖,同时保留热更新体验。 + +| 项 | 约定 | +|---|---| +| 前端 | 继续 Vite `:3100`;API 代理 → `127.0.0.1:8080`。生产静态由 embed 提供,dev 不强制走 embed。 | +| 后端 | `go run` / `bin/server`;`ENV=dev`,`DATA_DIR=./data/dev`,`LOCALPG_MODE=managed`,`PGDATA=$DATA_DIR/pg` | +| PI | 本机 sidecar `:18865`;模型保持 **M2.7-highspeed** | +| 启动 | `scripts/launch.sh --no-docker`:managed PG + sidecar + server + Vite;原 compose 路径保留为 `--docker`(默认可暂保持现行为,文档标明迁移日程) | +| demo seed | 语义不变;不因部署形态放宽生产红线 | + +验收(工程层):`go test -short` 相关包、preflight 过、本机 `/health`/`/ready`;产品链路仍按验证契约在获授权时用真实 Runner。 + +### 4.2 test — 内部测试部署 + +**目标**:单二进制首次完整落地;对齐 rc 晋升。 + +| 项 | 约定 | +|---|---| +| 前置 | `postgresql-16` + `pgvector` + `node ≥ 22`;`preflight.sh` 缺项即失败 | +| PG | 默认 `attach`(内部机常由运维预装)或 `managed`(单人测试机);端口语义 **5434** | +| HTTP / PI | **8081** / **18866** | +| 配置 | `ENV=test`,`SEED_DEMO_USERS=false`,模型 **MiniMax-M3** | +| 安装 | 解包 tar.gz → preflight → 写入 `/etc/agent/test.env`(或 `$DATA_DIR/.env`)→ `systemctl enable --now agent-server-test` + `pi-runner-test`(可非开机自启,按站点策略) | +| 晋升 | `promote-to-test.sh` / promotion-receipt **门禁不变**;新增:**从 rc tag 源码构建** `agent-server--linux-amd64.tar.gz`,**sha256 写入收据** | +| 验收 | 验证契约「产品 PI 基线」:真实 Runner 全链路 + `/health` + `/ready` + 范围冒烟;报告入 `.doc/test-reports/` | + +### 4.3 main — 生产上线 + +**目标**:可运维、可备份、密钥与现 compose 硬校验等价;须**单独授权**。 + +| 项 | 约定 | +|---|---| +| PG | **强制 `attach`**:独立 `postgresql` systemd 单元;便于 `backup-system-db.sh`、崩溃隔离、小版本升级 | +| HTTP / DB / PI | **8000 / 5435 / 18867** | +| 密钥 | `EnvironmentFile=/etc/agent/main.env`(模式 `0600`);启动前 preflight 强校验:`SYSTEM_DB_PASSWORD`、`ADMIN_PASSWORD`、`RUNNER_AUTH_TOKEN`、`KB_DB_PASSWORD`;复用 `validateProductionSecrets` | +| 重启 | systemd `Restart=always`(等价 compose) | +| 就绪 | 进程内:迁移完成 + events 消费者就绪 → `/ready` | +| 红线保持 | `ALLOW_IN_MEMORY=false`、`AUTH_REGISTRATION_ENABLED=false`、`FAV_DEGRADED_READ=false`、`FAV_PUBLISHER_ENABLED=false`;不因形态变更放宽 [gap-matrix](../remediation/gap-matrix.md) | +| 发布 | `release-to-main.sh` 流程不变;`install-main.sh` **仅授权后**执行;制品身份(tag + sha256)入账 | + +--- + +## 5. 交付物与构建 + +### 5.1 产物布局 + +```text +agent-server--linux-amd64.tar.gz +├── agent-server # 单二进制 +├── pi-runner-sidecar/ # 外置 +├── deploy/systemd/ +│ ├── agent-server-dev.service +│ ├── agent-server-test.service +│ ├── agent-server-main.service +│ ├── pi-runner-dev.service +│ ├── pi-runner-test.service +│ └── pi-runner-main.service +├── scripts/preflight.sh +├── scripts/install-test.sh # 内部测试 +├── scripts/install-main.sh # 生产;需授权标记 +└── SHA256SUMS +``` + +### 5.2 构建脚本(拟)`scripts/build-single-binary.sh` + +1. `web/`:`env -u VITE_ENABLE_DEMO_SEEDS npm ci && npm run build`(含 precompress) +2. 可选跑 `scripts/check-prod-bundle.sh` +3. `CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="-s -w -X main.version=…" -o dist/agent-server ./cmd/server` +4. 组装 sidecar(钉扎 `pi-coding-agent` 版本与 Dockerfile 一致) +5. 打包 tar.gz + `sha256sum` + +构建机需要 Node(仅构建前端与 sidecar),目标运行机:Go 二进制无 Node(除 sidecar 外)。 + +### 5.3 环境变量对照(摘录) + +| 变量 | 作用 | main | +|---|---|---| +| `ENV` | `dev`/`test`/`main` | `main` | +| `LOCALPG_MODE` | managed/attach/off | `attach` | +| `APP_DB_DSN` / `CONTEXT_*` | 业务库 | 必填 | +| `POSTGRES_SHARED_KB_DSN` | 共享 KB | 必填 | +| `PI_AGENT_RUNNER_URL` | Runner | 必填 + Token | +| `DATA_DIR` | 业务数据根 | `./data/main` 或绝对路径 | +| `HTTP_PORT` | 监听 | 8000 | + +完整列表以 `.env.example` / `configs/.env..example` 为 SSOT;实施阶段同步增补 `LOCALPG_*` 键说明。 + +--- + +## 6. 实施阶段与验证 + +| 阶段 | 内容 | 验证(按契约选层) | +|---|---|---| +| **P1** 资产嵌入 | webdist/configs/goose embed;静态与 loader 双通道 | Go short 测 + 手工:无磁盘 dist 时仍能出 index;有磁盘覆盖优先 | +| **P2** events 合并 | in-process 消费者;ready 门闩;cmd/events 保留 | 单元/集成:投递→消费;ready 前后行为 | +| **P3** localpg | managed/attach/off + 优雅停 | 临时 PGDATA 冒烟;attach 负例(无 DSN 拒启) | +| **P4** 打包与单元 | build 脚本、sidecar、systemd、preflight、`launch.sh --no-docker` | 产物 sha;preflight 缺项;dev 无 docker 拉起 | +| **P5** |dev 全链路| | 工程冒烟 +(授权时)真实 PI | +| **P6** |test 部署演练| | rc 构建 + 安装 + 产品 PI 基线 + 报告 | +| **P7** |main(单独授权)| | release 制品 + install-main + gap-matrix 复核 + 生产冒烟 | + +纯本设计文档任务的验收:**可审方案落盘 + 链接/拓扑/门禁一致性**;不记产品测试 PASS。 + +--- + +## 7. 风险与缓解 + +| 风险 | 环境 | 缓解 | +|---|---|---| +| pgvector `.so` 不随二进制分发 | 全环境 | preflight 检测;安装文档写明发行版包名 | +| 二进制体积 +~11MB(web/dist) | 全环境 | `-s -w`;后续可考虑压缩 embed(非必须) | +| embed 后模板热更新丢失 | 主要 main | 磁盘覆盖优先;运维可挂载补丁目录 | +| 与 compose 并存期状态噪音 | |dev| | `launch.sh` 明确互斥;文档标明切换步骤 | +| rc 产物未接入收据 | |test| | P6 把 sha256 写入 promotion-receipt 字段 | +| PG 子进程 vs 独立服务 | |main| | 本方案定 attach;managed 禁止作为生产默认 | +| 密钥从 compose 迁 EnvironmentFile | |main| | 0600 + preflight;禁止提交 env;操作审计记路径不记值 | +| 并发文档任务占用 `.doc` scope | 治理 | 本任务以文件级 scope 注册;与 `member-permissions-doc` 文件不重叠 | + +--- + +## 8. 与现有规范的一致性声明 + +- **端口 / 数据路径 / 共享 KB**:与 [PROJECT.md](../../PROJECT.md) 表一致,不另起拓扑。 +- **晋升**:dev→test(rc)→main(release)脚本与收据门禁保留;仅增加二进制制品身份。 +- **验证**:实施后各阶段按 [验证契约](../ops/2026-09-21-validation-contract.md) 选层;产品链路禁止 stub 冒充 PASS。 +- **红线**:FAV live / 注册关闭 / 禁止内存降级等与 compose main 对齐,不因非容器化放宽。 +- **写入治理**:实施须新开 feature worktree + `agentctl` 租约;共享 CURRENT/MATRIX 走 docs apply。 + +--- + +## 9. 改造点清单(实施时回链) + +| # | 改造 | 关键路径 | 阶段 | +|---|---|---|---| +| 1 | webdist embed + 磁盘优先 | 新 `web/embed.go`;`internal/server/static_assets.go` | P1 | +| 2 | configs embed | 新 `configs/embed.go`;`internal/template/loader.go` | P1 | +| 3 | goose `SetBaseFS` | `internal/db/migrate.go`;新 embed 包 | P1 | +| 4 | events 合并 | `cmd/events` → `internal/app/eventsconsumer`;`cmd/server` | P2 | +| 5 | localpg | 新 `internal/localpg/` | P3 | +| 6 | 构建/安装/systemd | `scripts/build-single-binary.sh`、`deploy/systemd/`、`preflight.sh` | P4 | +| 7 | launch 无 docker | `scripts/launch.sh`;`deploy/pi-agent-sidecar/` | P4 | +| 8 | 环境验收 | P5–P7 见上 | P5–P7 | + +--- + +## 10. 开放问题(实施前确认) + +1. test 内部机默认 `attach` 还是 `managed`?(本设计允许二者,站点选一写入 `configs/.env.test`) +2. sidecar 是否 vendor 完整 `node_modules`,或安装时 `npm ci --omit=dev`?(体积 vs 可复现) +3. 共享 KB 在「完全离线单机演示」场景是否允许 managed 同实例双库作为正式支持模式? + +--- + +## 11. 修订记录 + +| 日期 | 说明 | +|---|---| +| 2026-09-24 | 初稿:调研三环境 compose/launch/embed 现状;确认纯单文件 + managed/attach 分级;覆盖 dev/test/main |