From 1a958cb1029a0c8ea3e137f69244b9f904c19483 Mon Sep 17 00:00:00 2001 From: Tianyu Liu Date: Mon, 24 Aug 2026 05:59:11 +0200 Subject: [PATCH] M8-R07A: remove obsolete WarmteLink overlay references --- docs/design/m8-warmtelink-energy.md | 47 +++++++++++++++++------------ 1 file changed, 28 insertions(+), 19 deletions(-) diff --git a/docs/design/m8-warmtelink-energy.md b/docs/design/m8-warmtelink-energy.md index f5c71d4..1329898 100644 --- a/docs/design/m8-warmtelink-energy.md +++ b/docs/design/m8-warmtelink-energy.md @@ -245,10 +245,13 @@ M8 的 schema 变更沿现有单一 `alembic_app` 链按下表串行落地;不 - serial 默认 `115200`、`7` data bits、no parity、`1` stop bit;设备路径必须是 `/dev/...`。 - `warmtelink_serial` config 保存路径和串口参数,不保存 telegram/equipment id;敏感字段采用现有 secret mask 约定。 -- 新增可选 `docker-compose.warmtelink.yml` overlay,把宿主机稳定 `/dev/serial/by-id/...` 映射为 - 容器内 `/dev/warmtelink`,通过宿主机 serial GID 授权。pyserial 在 POSIX 以 `O_RDWR` 打开,故 device - rule 的最小系统权限为 `rw`(不含 `m`);容器仍非 root/非 privileged,worker 业务只 read/close、绝不 write。 -- 默认 `docker-compose.yml` 在没有硬件时仍可启动,不强制声明不存在的 device。 +- 现有 base+dev Compose 通过 `WARMTELINK_DEVICE_PATH` 与 `WARMTELINK_SERIAL_GID` 环境变量,把宿主机稳定 + `/dev/serial/by-id/...` 直接映射为容器内 `/dev/warmtelink`,并以宿主机 serial GID 授权。pyserial 在 POSIX + 以 `O_RDWR` 打开,故 device rule 的最小系统权限为 `rw`(不含 `m`);容器仍非 root/非 privileged,worker + 业务只 read/close、绝不 write。 +- 当前 base+dev Compose 要求在 `.env`(或等效部署环境)中同时提供 + `WARMTELINK_DEVICE_PATH` 与 `WARMTELINK_SERIAL_GID`,并固定声明该 device 映射;没有有效硬件路径和 + serial GID 的部署不能把 Compose 当作“无硬件可启动”的配置。 - source disable/delete/config change 必须停止旧 worker;shutdown 不留下线程或打开的 serial fd。 ## 8. 前端信息架构 @@ -1068,14 +1071,15 @@ T01~T06 先把现有 DSMR 安全迁到统一 source/binding;T07~T11 再接 - 人工用小数费率核对请求 body 与展示值未被 float 改写。 - 同时启用两 scope、换 Meter、无一侧 thermal Meter 时,页面文案与 summary 是否诚实。 -### M8-T20 — 部署 Overlay、运行文档与端到端收尾 [structural] +### M8-T20 — 部署 Compose 配置、运行文档与端到端收尾 [structural] - **Status**: `done` - **Depends**: M8-T19 - **Context**: 最后一张卡把串口权限、操作 runbook 与隔离的自动化技术验收变成可重复验收结果;真实硬件/HA 观察作为交付后由用户执行的人工 walkthrough,不是 agent 或 Reviewer 的技术 PASS 前置条件。 **Files** -- `create docker-compose.warmtelink.yml` +- `modify docker-compose.yml` +- `modify docker-compose.dev.yml` - `modify tests/test_deployment.py` - `create docs/warmtelink-energy.md` - `modify docs/architecture-overview.md` @@ -1087,14 +1091,16 @@ T01~T06 先把现有 DSMR 安全迁到统一 source/binding;T07~T11 再接 - `modify docs/design/m8-warmtelink-energy.md` **Steps** -1. 新增可选 compose overlay:示例把宿主 `/dev/serial/by-id/` 映射为容器 - `/dev/warmtelink`,以显式 serial GID/additional group 授权;服务保持非 root,默认 compose 无硬件 - 也能启动。不要写入用户真实设备 id。 -2. 检查 Dockerfile/compose/build context 与新 Python/前端文件;deployment tests 覆盖默认 compose、 - overlay 合并、device path、pyserial `O_RDWR` 所需的 `rw`/无 `m`、非 root/非 privileged、migration - 无 device、COPY source 存在。 -3. 写运行文档:识别稳定 by-id、查 GID、启停 overlay、创建 source、discover/bind、质量含义、 - reconnect/权限排障、backup/migration、合同录入、HA toggle 与安全回滚。明确不删除旧 config/data。 +1. 初始交付曾使用独立 Compose 配置文件;该形态已由 M8-R07 后续修订收敛为现有 base+dev Compose。示例通过 + `WARMTELINK_DEVICE_PATH=/dev/serial/by-id/` 和 `WARMTELINK_SERIAL_GID=` 直接映射容器 + `/dev/warmtelink`,以显式 serial GID/additional group 授权;服务保持非 root。当前 base+dev Compose + 明确要求这两个环境变量并固定声明 device 映射,不能作为无硬件启动形态使用。不要写入用户真实设备 id。 +2. 检查 Dockerfile/compose/build context 与新 Python/前端文件;deployment tests 覆盖默认及 base+dev compose + 合并、device path、pyserial `O_RDWR` 所需的 `rw`/无 `m`、非 root/非 privileged、migration 无 device、COPY + source 存在。 +3. 写运行文档:识别稳定 by-id、查 GID、在 `.env`(或等效部署环境)配置 stable by-id path 与 serial GID, + 由 Compose 固定映射串口;创建 source、discover/bind、质量含义、reconnect/权限排障、backup/migration、 + 合同录入、HA toggle 与安全回滚。明确这两个变量为必填项,不删除旧 config/data。 4. 在 `/tmp` 下构造的隔离合成历史数据库演练 Alembic 14→head 并对账;新空库迁移到 head。 不挂载、复制或打开运行中 production 的数据库、容器或 volume。 5. 只用 mock/fake serial、合成 source/channel/binding/Meter/contract/cost/HA payload 和 `/tmp` @@ -1112,7 +1118,7 @@ T01~T06 先把现有 DSMR 安全迁到统一 source/binding;T07~T11 再接 - 不自动 push、force-push 或打 release tag。 **Acceptance criteria** -- [ ] **自动化技术验收**:默认 compose 与 synthetic overlay 的结构检查通过;overlay app 仍为非 root/非 privileged,device rule 为无 `m` 的 `rw`(仅满足 pyserial `O_RDWR` 打开),worker 业务只 read/close,migration 无 device。 +- [ ] **自动化技术验收**:默认 compose 与 synthetic base+dev 配置的结构检查通过;app 仍为非 root/非 privileged,device rule 为无 `m` 的 `rw`(仅满足 pyserial `O_RDWR` 打开),worker 业务只 read/close,migration 无 device。 - [ ] **自动化技术验收**:mock/fake serial 覆盖采集、断线与只读边界;合成 source/channel/binding/Meter、thermal/electricity contract/cost 与 HA payload 覆盖完整身份链和成本/HA 行为,绝不连接真实 serial、HA 或 MQTT。 - [ ] **自动化技术验收**:仅在 `/tmp` 合成历史副本演练 rev14→head 并对账 DSMR 正常数字、source/binding、Meter、contract 和 cost;空库→head 及重复运行通过,绝不打开、复制、挂载或修改 production DB/config/container/volume。 - [ ] **自动化技术验收**:`pytest`、`ruff check .`、OpenAPI/codegen、全部前端闸门和 Docker build 全绿;临时 Docker 运行只使用无 volume/bind/device、无 production 挂载的容器及容器内临时数据库,关键路由不 500,结束后清理容器、image tag、`/tmp` 文件与测试凭据。 @@ -1167,10 +1173,13 @@ T20 的 agent/Reviewer 自动化技术验收完成后,最终报告必须将以 可回滚部署、真实 serial 设备和真实 HA 环境中自行执行并验收;这不是 Reviewer 技术 PASS、T20 状态更新或 M8 收尾的前置条件。agent 不得执行、记录为已执行,或以 mock/临时容器结果替代这些人工观察。 -1. 不启用 overlay 启动默认 stack,确认 app、现有 DSMR、Modbus、电价/电费和前端均无回归。 -2. 以 stable by-id + serial GID 启用 overlay;容器保持非 root/非 privileged,`/dev/warmtelink` 的 device - rule 为 pyserial POSIX `O_RDWR` 所需的 `rw`(没有 `m`),并记录可成功打开。该系统权限不等于业务写入: - 代码只 read/close,绝不调用 write。 +1. 在 `.env`(或等效部署环境)设置 `WARMTELINK_DEVICE_PATH=/dev/serial/by-id/` 与 + `WARMTELINK_SERIAL_GID=`,启动当前 base+dev Compose stack,确认 app、现有 DSMR、Modbus、 + 电价/电费和前端均无回归;不得把缺少这两个值的配置当作无硬件启动模式。 +2. 确认当前 base+dev Compose 的固定映射:容器保持非 root/非 privileged,`/dev/warmtelink` 的 device rule + 为 pyserial POSIX `O_RDWR` 所需的 `rw`(没有 `m`),并记录可成功打开。该系统权限不等于业务写入:代码只 + read/close,绝不调用 write。若要运行 Pre-M8 probe,必须先停止 app,保证串口只有一个 owner,完成后再恢复 + 当前 `.env` 直配部署。 3. UI 创建 WarmteLink source,discover 后看到两个 channel、正确 unit/device type、质量 `unverifiable`;原始 equipment id 在日志、DB、API、UI 均不可见。 4. 分别创建/选择 heating 与 hot_water Meter 并确认 binding;观察 latest 约 10 秒更新、history