6.5 KiB
6.5 KiB
id, title, phase, deps, status, created, issue, context_ref, claim_branch, work_branch, write_paths
| id | title | phase | deps | status | created | issue | context_ref | claim_branch | work_branch | write_paths | |||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| T-015 | 建立 Bell 事件 v0.1 校验与不可变 PostgreSQL 存储 | 3 |
|
TODO | 2026-08-10 | 51 | null | null | null |
|
问题 / 背景
M3 要求 Bell 首次真实消费冻结的事件契约 v0.1,生成平台 ULID,并把事件事实保存为不可变记录。当前 Bell 只有目录占位,PostgreSQL 也只有 Site/Area 投影源表;如果先做规则或 Alert,会把未经校验、可被覆盖的事件数据变成后续状态机的错误基础。
冻结契约中还存在一处文档自相矛盾:docs/raw/contracts/README.md 的修订记录、雷达示例和 JSON Schema 均允许非成像事件的 snapshot_uris=[],但 §5 的旧句仍把空数组列为 schema 可拒绝项。本任务先把该句校正为现有冻结事实,不修改 schema 或字段语义。
关联需求与交互(如适用)
- 用户故事:无直接 UI;为 US-003、US-004、US-006 的后续事件/处置流程提供数据基础。
- 交互清单:不适用;本任务不实现 Bell Web/H5 页面或公共查询 API。
- 相关页面 / 路由:不适用。
方案
- 在
Bell/建立独立 Go module,复用项目冻结的 Go 1.26.5、PostgreSQL 17.10 和pgx/v5 v5.10.0;冻结 Draft 2020-12 校验器与 ULID 库版本、许可证和退出路线,不引入前端或消息总线。 - 把冻结 schema 逐字节复制到
Bell/contracts/event-v0.1.schema.json并以测试阻止漂移。Bell 内部 ingest factory 接收不含平台id的候选事实,拒绝上游自报id,由 Bell 生成evt_ULID 后再执行 schema 与代码级断言。Brain→Bell 的 HTTP/消息总线 transport 继续待定,本任务不借内部 Go 类型冻结公共网络协议。 - 代码级校验覆盖时间顺序/延迟自洽、
confidence=null、证据 URI 脱敏、唯一 primary 且与顶层设备一致,以及视频隐私准入。隐私与客户敏感名称通过必需 port 注入;解析/映射不可用时失败关闭,不使用 allow-all 生产默认值。 - 新增 Bell event repository。
bell.events保存最终规范化 JSON、摘要和可查询的最小索引字段;平台 ID 冲突时仅允许“同 ID + 同摘要”的幂等重放,不同摘要稳定冲突。后续 outcome 写入独立的 append-onlybell.event_outcomes,不得更新原事件事实。 - migration 增加独立 NOLOGIN
bell_runtime最小权限角色。migration ownerbell_app持有对象;运行时只获得必需的SELECT/INSERT,明确没有事件表的UPDATE/DELETE/TRUNCATE,并以数据库 trigger 拒绝事实改写。生产/共享实例仍由管理员离线 migration,不由 Bell 高权限自迁移。 - 扩展隔离 PostgreSQL 17.10 harness,使用
bell_runtime登录运行真实 repository/权限/重放/不可变性集成测试;同步根启动入口、技术栈、架构、API 状态和当前仓库现实。
不可变约束
- 阈值 / 数值边界:请求体/单事件规范化 JSON 上限 1 MiB;延迟自洽误差严格小于 100 ms;事件列表/公共 API 不在本任务内;任何默认 16 路值不成为事件数量上限。
- 判定式 / 状态转换:Bell 是
evt_ULID 唯一生成者;候选事实不得携带id;最终事实必须同时通过 Draft 2020-12 schema 和 README 六项代码级断言。相同平台 ID/相同摘要为幂等成功,相同 ID/不同摘要为冲突;原事件永不 UPDATE/DELETE,后续 outcome 只能追加。 - 安全边界:未知顶层字段拒绝;视频隐私映射或敏感名称策略不可用时失败关闭;普通错误和测试证据不回显事件全文、证据 URI、客户名、凭据或内部堆栈;
bell_runtime不拥有 migration 对象且没有事件事实改写权限。 - 既有契约:
docs/raw/contracts/event-v0.1.schema.json字段、枚举与 v0.1 语义不变;只修正文档中与 schema/示例冲突的旧句。Brain transport、规则、Alert、证据回捞、RBAC/JWT/OIDC 和事件公共 API 均另立任务。
验收要点
- 任务相关验证:
go -C Bell test ./...、go -C Bell vet ./...、go -C Bell build ./...;python -m unittest discover -s tests -p "test_bell_event_contract.py" -v;验证三个冻结示例、负向 schema/六断言、ULID 所有权、幂等冲突和 append-only outcome。 - 完整门禁:因命中 Bell 脚手架、PostgreSQL migration、权限、根启动入口和冻结契约消费者,运行
./scripts/test_postgres.ps1 -PgRoot D:\pgsql17、./init.ps1、三条 Python 治理命令和git diff --check。隔离测试必须证明现有 5432 listener 前后不变并自动清理临时集群。 - 人工 / 设备验收:不适用;本任务不依赖摄像头、客户网络、GPU、MinIO 或产品 UI。生产上线仍受法务/客户留存政策和 M3 现场 dry-run 门禁约束。
- 构建产物:
go -C Bell build ./...可构建全部 Bell 包;不生成可部署 Bell API 二进制,因为 Brain transport、认证和公共 API 尚未冻结。
边界(不改什么)
- 不实现 Brain mapper/投递、HTTP 或消息总线事件入口、规则引擎、Alert、ack、升级链、对象存储、证据切片、反馈回流、Bell Web/H5 或 JWT/OIDC。
- 不修改冻结事件 schema、示例字段或 Sense 业务代码;不把整数事件契约 ID 与现有文本逻辑 ID 的待定映射悄悄固化为跨系统规则。
- 不把
bell_appowner 凭据交给运行进程,不在仓库保存 DSN、密钥、客户数据、真实事件或真实证据 URI。
协作约束
- 责任 Agent:codex
- 唯一写入者:codex
- 委派:不启用。
- Gitea:Issue、
context_ref、claim 与工作分支在双向映射及 dispatcher 分配后回填。
任何新增写路径先检查与其他活跃任务是否重叠;同一时刻只有一个 Agent 修改本任务的 write_paths。
执行记录
- 2026-08-10:按 M3 建议拆出本任务;完成仓库/远端状态检查和
./init.ps1基线,现有 58 个 Python 测试及 Sense generate/test/vet/build 全部通过。实现尚未开始。