Files
yovision/docs/raw/08-三系统职责划分.md
T
QiuSW e0b0bfafeb
Harness governance / validate (push) Has been cancelled
Harness governance / validate (pull_request) Has been cancelled
docs(design): close Sense second-review gaps
2026-08-04 11:08:41 +08:00

188 lines
12 KiB
Markdown
Raw 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.
# 三系统职责划分:Sense / Brain / Bell
> 本文档回答一个问题:**一段代码该写进哪个目录。**
> 划分依据来自《03-通用场景应用方案》的 L0–L5 分层与组件选型,本文档只是把它按三个可独立开发的系统重新切分。
> 定稿:2026-08-03
---
## 1. 三系统总表
| | **Sense** | **Brain** | **Bell** |
| --- | --- | --- | --- |
| 中文 | 感知系统 | 推理系统 | 管理系统 |
| 小学生版 | 感觉到 | 想一想 | 打铃叫人 |
| 对应层 | L1 接入 | L2 流水线 + L3 算法 | L4 业务 + L0 基座 |
| 语言 | Go | Python / CUDA | Go + 前端 |
| 有无状态 | 有(设备台账) | **无状态** | 有(事件、告警) |
| DB schema | `sense` | 无 | `bell` |
| 契约角色 | 供流与信号 → Brain | **产出**事件 | **消费**事件 |
| 首次交付 | M1 | M3 | M3(最小)→ M4(完整) |
### 1.1 各自装什么
**Sense —— 把现场的流和信号稳定地拿进来并管住**
- 设备台账(`devices`,含 `modality`:video / radar / contact / button / wearable / other,以及决定成像、媒体、遥测、空间配置等页面与操作的 `capabilities`)
- ONVIF 客户端:连接、GetProfiles、GetStreamUri、SetSystemDateAndTime
- mediamtx API 客户端(**自行用 oapi-codegen 从其 OpenAPI 生成**,不依赖第三方 SDK)
- **对账器**:水平触发、`sync_state`、独立信号量、10% 孤儿删除安全闸、只收敛不回滚
- 探活与断线重建
- WireGuard 控制面隧道
- mediamtx 鉴权回调(401 + 踢流是四种停用粒度之一)
- 容量配额执行:设备新增/启用时读取 Bell 的站点配额,只拒绝超额变更;配额服务暂时不可用时不影响已有流
- Area 准入执行:消费 Bell 的版本化 `capture_policy` 投影;策略不可用时只拒绝相关新写入,不静默中断已有设备
- 流绑定与媒体分片调度:维护 `mtx_instance`,默认 16 路交付;扩到 128 路时按 `media_shard.max_streams` 横向分片
- 边缘节点 agent:推流、本地环形缓冲、断网续传
- **设备型触发源**:雷达、门磁、按钮、ONVIF 事件订阅
- 非视频传感器的信号接收(signal plane,不走 mediamtx)
**Brain —— 看画面、出判定**
- Savant 流水线与适配器(ZeroMQ 边界,适配器故障隔离,实时模式丢帧)
- 模型:检测 / 姿态 / 跟踪 / ReID(`anon_id`)/(M5)人脸
- **`Detector` 与 `PoseEstimator` 接口解耦**——这是 AGPL 逃生通道的前提,换 YOLOX + RTMPose 时判定算法不动
- 判定内核:几何证据 + 时间窗状态机(从 silver_pose 抽取,两边共用)
- 事件 mapper:判定结果 → 事件契约 v0.1
- **像素级**运动侦测触发(要解码,所以在这里)
- 推理 worker 注册与分片:单逻辑推理分片默认最多 16 路;64/128 路由多个 worker 承担,路由变更不改判定代码
**Bell —— 记录、派发、追到人确认**
- 事件接收与校验(schema 校验 + 契约 README §5 那六条代码级断言 + 生成 ULID)
- 事件存储:**不可变**,误判只改 `outcome`
- 规则引擎 + 场景包加载
- 告警状态机:升级链、ack、抑制、静默(**≤4h,无永久选项**)
- 投递:push / 短信 / 语音,**双供应商**
- 误报反馈闭环:`outcome` 回写 Brain
- Tenant/Site/Area、`capture_policy`、多租户 RBAC、`tenant_features`(人脸授权开关:未授权时能力在 API 与 UI 中**不可见**,不是禁用)
- 全局审计日志;接收 Sense 设备操作审计并保留来源上下文
- 站点容量配额的唯一真相源:`site.max_video_channels` 默认 16、上限 128;提供版本化内部读取接口/投影给 Sense 执行
- 管理后台前端 + 大屏:按 128 路设计分页/虚拟列表、筛选与批量操作,不一次性加载全部视频
### 1.2 不属于任何一个目录的东西
| 组件 | 说明 |
| --- | --- |
| **mediamtx** | 独立二进制,外部依赖。Sense 管它的配置与生命周期,`Sense/deploy/` 放基线配置 |
| **PostgreSQL / MinIO / Prometheus** | 基础设施,独立部署清单 |
| **silver_pose** | 独立仓库,是 Brain 判定内核的来源与单机演示形态。**不改名、不合并**——它现在能卖,Brain 还不能 |
| **`_reference/`** | 只读参考源码(如 MiBeeNvr)。按《03》§1.4 白名单借鉴 ONVIF、IP 自愈、健康检测、测试组织与 UI 交互;禁止复制媒体内核、SQLite 真相源、AI/用户体系,禁止整仓进生产或加入 go.mod |
---
## 2. 目录结构
### 2.1 Sense(Go)
```
Sense/
├── cmd/
│ ├── sense-api/ 控制面服务:设备台账、鉴权回调、对账器
│ └── sense-agent/ 边缘节点:推流、环形缓冲、隧道
├── internal/
│ ├── device/ 设备台账(devices,含 modality + capabilities)
│ ├── onvif/ 连接、GetProfiles、GetStreamUri、SetSystemDateAndTime
│ ├── mtx/ oapi-codegen 生成的 mediamtx 客户端 + 薄封装
│ ├── reconcile/ 对账循环(幂等 + 退避 + 安全闸)
│ ├── probe/ 探活
│ ├── trigger/ 设备型触发源(雷达/门磁/按钮/ONVIF 事件)
│ ├── tunnel/ WireGuard 控制面
│ ├── authcb/ mediamtx 鉴权回调
│ └── store/ M1 先 SQLite,schema 与生产 Postgres 保持一致
├── deploy/
│ └── mediamtx.yml 基线配置
└── api/openapi.yaml
```
### 2.2 Brain(Python / CUDA)
```
Brain/
├── pipeline/ Savant 流水线定义与适配器
├── models/
│ ├── detector/ Detector 接口 + YOLO / YOLOX 实现
│ ├── pose/ PoseEstimator 接口 + YOLO-pose / RTMPose 实现
│ ├── tracker/ ByteTrack / BoT-SORT
│ └── reid/ 匿名同一性,产出 anon_id
├── judge/
│ ├── evidence.py 几何证据(躯干角、髋部下坠比)
│ └── state.py 时间窗状态机 NORMAL/SUSPECT/CONFIRMED/RECOVERING
├── emit/
│ ├── mapper.py 判定结果 → 契约 v0.1
│ └── publisher.py 投递(HTTP 起步 → ZeroMQ);**失败落本地队列重试,不阻塞主链路**
├── trigger/ 像素级运动侦测
└── contracts/ ← 与 Bell/contracts/ 逐字节相同
```
### 2.3 Bell(Go + 前端)
```
Bell/
├── cmd/bell-api/
├── internal/
│ ├── ingest/ 接收事件、schema 校验、六条断言、生成 ULID
│ ├── event/ 事件存储(不可变,只允许追加 outcome)
│ ├── rule/ 规则引擎 + 场景包加载
│ ├── alert/ 告警状态机、升级链、ack、静默
│ ├── deliver/ push / 短信 / 语音,双供应商
│ ├── feedback/ 误报回流,outcome 回写 Brain
│ ├── tenant/ 多租户 RBAC、tenant_features
│ ├── audit/ 审计日志
│ └── store/ Postgres(schema: bell)
├── web/ 管理后台前端
├── packs/ 场景包(**纯配置** —— M5 架构验收点)
└── contracts/ ← 与 Brain/contracts/ 逐字节相同
```
> `contracts/` 只在 Brain 与 Bell 各存一份(生产者与消费者),**Sense 不需要**——它不碰事件契约。
---
## 3. 八条边界(不写死就会漂)
| # | 边界 | 定论 |
| --- | --- | --- |
| 1 | mediamtx 二进制归谁 | 独立进程。**Sense** 管配置与生命周期,部署清单放 `Sense/deploy/` |
| 2 | 触发源归谁 | 按性质切:**设备型**(雷达/门磁/按钮/ONVIF 事件)→ Sense,它们本来就是设备;**像素级**运动侦测 → Brain,它要解码 |
| 3 | pre-roll 证据切片谁裁 | 录制在 Sense(mediamtx),事件在 Brain 产出。**Bell 发起回捞**(它拥有事件),Sense 提供切片接口 |
| 4 | ULID 谁生成 | **Bell**。Brain 只填 `source_event_id`。见契约 README §4 |
| 5 | 一个 PostgreSQL 还是三个 | **一个实例,schema 分离**(`sense` / `bell`),Brain 无 schema。"DB 是唯一真相源"是对账器成立的前提,拆库即失效 |
| 6 | 16 路与 128 路分别指什么 | **16 路是默认交付规格,128 路是本阶段单逻辑站点上限**,都不是“单进程/单服务器保证值”。媒体与推理必须横向分片;单机承载量由分辨率、码率、帧率、模型和硬件基准测试决定 |
| 7 | 站点配额谁拥有、谁执行 | **Bell 拥有 `sites.max_video_channels`,Sense 在设备新增/启用写路径执行**。通过版本化内部 API 或只读投影同步,不允许 Sense 直接写 Bell schema;依赖暂时不可用时拒绝新变更,但已有视频链路继续运行 |
| 8 | 设备模态与隐私准入怎么建模 | 台账使用 `modality + capabilities`,不以摄像头作为唯一根实体;**Bell 拥有 Area 与 `capture_policy`,Sense 消费带版本投影并按设备 `captures_image` 能力在新增/启用写路径执行**。策略不可用时拒绝相关新变更并告警,已有链路不静默停用;M1 固化模型,M6 再增加非视频适配器 |
| 9 | 接入操作审计怎么进入 Bell | Sense 在同一事务写设备期望态和持久化 outbox,再由幂等 relay 异步汇入 Bell 全局审计;不得先执行高风险操作再尽力入队。字段、签名、重放和留存由独立 API/契约任务冻结 |
第 2、3、6、7、8、9 条是本文档新定的,若实施中发现更合适的切法,改这里并同步《02》《03》。
---
## 4. 标识符约定
```
仓库/目录 Sense Brain Bell
镜像 yov/sense:x.y yov/brain:x.y yov/bell:x.y
日志/指标前缀 sense_ brain_ bell_
三字母码 SEN BRN BEL
DB schema sense — bell
```
**命名规则:系统名不得是该系统领域模型里的实体名。**
`bell` 域内有 `alerts` 表 → 系统不能叫 Alert(`alert.alerts` 无法读,且撞 Prometheus 内置的 `ALERTS` 序列)。另两个同样干净:`sense` 域内是 `devices`/`streams`,`brain` 域内是 `models`/`detections`。
---
## 5. 里程碑与目录的对应
| 阶段 | 动哪个目录 |
| --- | --- |
| **M0** 摄像头兼容性验证 | 无生产代码;可直接运行 MiBeeNvr 等 `_reference/` 项目作为隔离实验室测试台,产物允许丢弃 |
| **M1** 5 路接入骨架 + mediamtx | **仅 Sense**;MediaMTX 正式进入,完整 MiBeeNvr 不得替代生产媒体数据面 |
| **M2** 对账器 + 多租户 + 隧道 + 16 路开通 | **仅 Sense**;至少一个站点验证默认 16 路配额与全流程 |
| **M3** 默认 16 路推理 + 规则引擎 + 事件预警 | **Brain + Bell 同时起步**,契约在此首次被真实使用 |
| **M4** 64 路分片 + 灰度 + 管理系统 | Sense 与 Brain 完成横向分片,Bell 完成 128 路规模下的列表与批量交互;验证单分片故障隔离 |
| **M5** 128 路容量验收 + 第二三场景包 + 触发式推理 + 人脸 | Sense/Brain 验证扩容不改业务代码;Bell 的 `packs/`(**纯配置**)+ Brain 的模型与触发 |
| **M6** 异构传感器 + 两级判定 | Sense 的 `trigger/` 与 `device/` 增加非视频协议适配器与能力实现(`modality + capabilities` 模型已从 M1 保留)+ Brain 两级判定 |
> M3 是契约第一次被真实使用的时刻。**在此之前契约允许原地修订,之后版本递增规则绝对生效**(契约 README §1)。