Files
yovision/docs/tasks/T-014.md
T
QiuSW 3af6a16740
Harness governance / validate (push) Has been cancelled
chore(task): claim T-014
2026-08-08 08:56:00 +08:00

9.0 KiB
Raw Blame History

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-014 建立 Sense 本地 16 路批量收敛与容量基线 2
T-012
DOING 2026-08-08 47 8ebb8ced49 claims/T-014 agent/codex/T-014
docs/tasks/T-014.md
Sense/README.md
Sense/scripts/t014-capacity.ps1
docs/00-ai-start-here.md
docs/03-tech-stack.md
docs/04-architecture.md
docs/06-tasks.md
docs/current-state.md
docs/research/sense-16-stream-capacity.md
tests/test_sense_capacity_contract.py

问题 / 背景

T-006 已证明一台准入实机与四条独立合成源可以完成五路实验室闭环,T-011/T-012 已实现 PostgreSQL Control API、最多 128 项批量期望态、多实例 fencing、孤儿安全闸和低基数指标;但 M2 的默认 16 路仍只有产品配额和单元测试,没有通过真实 HTTP 控制面完成 16 路创建、批量启停、MediaMTX 收敛、局部故障恢复和资源观测。项目当前没有客户网络环境,WireGuard T-013 暂缓,不能让该外部依赖阻塞本地软件容量基线。

本任务建立可重复的 Windows 本地 16 路实验室基准。它验证当前机器、固定软件版本和低码率无人物合成负载下的 Sense/PostgreSQL/MediaMTX 控制面与媒体拉流能力,不代表 16 台真实摄像头、客户网络、存储、AI/GPU 或生产 SLA。

关联需求与交互(如适用)

  • 用户故事:US-001、US-002、US-008、US-009;验证默认 16 路站点的批量接入与运维收敛基础。
  • 交互清单:IX-003、IX-004、IX-015、IX-016 的后端容量证据;不修改已确认 HTML 原型。
  • 相关页面 / 路由:复用冻结的 7 个 /api/v1 Control API endpoint、/metrics、MediaMTX v3 API;不增加公共接口。

方案

  1. 新增 Sense/scripts/t014-capacity.ps1 一键基准:校验冻结的 PostgreSQL 17.10、MediaMTX v1.19.3、FFmpeg 与 Go,使用随机回环端口和系统临时目录启动隔离 PostgreSQL、源 MediaMTX、生产 MediaMTX 与 Sense。migration 只读取并重放现有 001~011,不修改或连接本机已有 D:\pgsql17\data/5432。
  2. 先用 FFmpeg 生成 640×360、10 fps、H.264、无音频、无人物的短循环媒体夹具,再启动 16 个独立 FFmpeg -c copy RTSP publisher,每路有独立进程与 Path,可单独停止/恢复。预编码发布避免把 16 路软件编码开销计入 Sense/MediaMTX 基线;不把同一 publisher fan-out 冒充独立源。
  3. 在临时 PostgreSQL 中建立固定实验室 Tenant/Site/Area,Site 配额精确为 16;运行时生成 Control API opaque token、SHA-256 注册表和 cursor key,文件只存在于临时目录。通过真实 HTTP API 创建 16 个 disabled 视频设备,并验证第 17 个同站点设备稳定返回 quota_exceeded 且不写入台账。
  4. 使用真实 devices:batchDesiredState 和每台设备最新 ETag 执行 16 路批量启用、批量停用、再次启用;每次要求 operation 的 16 个结果全部成功。分别验证生产 MediaMTX 配置/运行 Path 为 16、0、16,设备最终状态与 generation/observed generation 收敛,unconverged=0。
  5. 在再次启用后同时停止固定四个 publisher,要求能观察到局部离线/未收敛且其余路径继续在线;恢复四个独立进程后自动回到 16 路在线和 unconverged=0。不得通过改数据库、人工编辑 MediaMTX 配置或重建进程集合掩盖失败。
  6. 正式稳定观察默认 30 分钟、每 10 秒采样。记录 Sense 与生产 MediaMTX 的归一化 CPU、working set、private bytes、handle 峰值,PostgreSQL连接峰值,以及 MediaMTX aggregate inbound bytes/吞吐、在线 Path、Sense 低基数指标和未收敛数。功能正确性有硬门禁;机器相关资源值只记录,不设置伪通用阈值。
  7. 脚本输出不含 token、DSN、端口清单、Path/source URI 或客户信息的 JSON 摘要;支持显式输出到仓库外路径。失败不输出成功结论,finally 停止全部叶子进程、停止临时 PostgreSQL并校验清理路径;可选调试短窗口必须标记 formal_eligible=false,不得作为正式验收。
  8. 将正式运行的硬件/软件版本、命令、功能时间、观察样本、资源统计、失败记录、限制和结论写入 docs/research/sense-16-stream-capacity.md,同步 README、架构、路线图和当前状态。增加静态契约测试,锁定 16/17/128/129 语义、无秘密输出、临时目录防护、真实批量 API、独立 publisher 和正式窗口规则。

不可变约束

  • 阈值 / 数值边界:正式源数精确为 16;Site 默认配额 16、允许范围 1~128,17 路在该 Site 必须拒绝,129 仍非法;批量 API 上限保持 128。正式观察不少于 30 分钟、采样周期 10 秒;局部故障固定 4 路且不得影响其余 12 路。短窗口只能 smoke。
  • 判定式 / 状态转换:16 个设备先 disabled 创建,随后 16 enabled → 16 disabled → 16 enabled;每轮批量结果必须全部成功。启用完成必须配置 Path=16、运行在线 Path=16、unconverged=0;停用完成必须配置 Path=0、设备 offline 且各自 observed generation 追平。四路故障恢复后必须再次满足 16 路在线和 unconverged=0。
  • 安全边界:只绑定随机回环端口;运行时 token/cursor key/DSN/临时路径不进入 Git、普通日志或结果摘要。脚本不得读取 ip_camera.env,不得访问客户网络或现有 PostgreSQL data/service;递归清理前必须验证目标位于系统临时目录且名称含 T-014 随机前缀。
  • 既有契约:不修改 Control OpenAPI v1、审计 v1/v2、MediaMTX 生成代码或数据库 migration;不把 16 写入业务数组/协议硬上限。T-001/T-006 的实机结论、T-007 真实五上游门禁与未来 T-013 WireGuard 均保持独立。

验收要点

  • 任务相关验证:先以短窗口运行脚本 smoke,再执行默认不少于 30 分钟的正式 16 路基准;验证 16 个独立 publisher、17 路配额拒绝、三轮批量状态、16/0/16 Path、四路故障隔离/恢复、最终 unconverged=0 和资源摘要。python -m unittest tests.test_sense_capacity_contract 锁定脚本安全/语义。
  • 完整门禁:./init.ps1、三条 Python 治理命令、go -C Sense test ./...、go -C Sense vet ./...、go -C Sense build ./...、./scripts/test_postgres.ps1 -PgRoot D:\pgsql17 和 git diff --check 全部通过;本任务不修改 Go 业务代码,但仍回归全部 Sense 包和 PostgreSQL v5。
  • 人工 / 设备验收:不需要摄像头、GPU、客户网络或客户数据。任务所有者核对 30 分钟原始 JSON 摘要、进程独立性和报告;真实摄像头/网络验收仍由 T-007/T-013 完成。
  • 构建产物:Sense/scripts/t014-capacity.ps1、docs/research/sense-16-stream-capacity.md、静态契约测试与同步文档;临时二进制、媒体、数据库、凭据和日志运行后删除,不提交。

边界(不改什么)

不实现或验证 WireGuard/T-013、客户网络、真实 16 摄像头、录像、下游 reader、AI 解码/推理、GPU、Bell UI/服务、Outbox relay、告警规则、跨 MediaMTX 分片或 64/128 路容量;不把本机资源样本转换为最低硬件规格或 SLA。本任务不解除 T-007,失败样本不得从报告中删除。

协作约束

  • 责任 Agent:由 dispatcher 分配。
  • 唯一写入者:同责任 Agent。
  • 委派:默认不启用。
  • Gitea:任务规格先进入默认分支,再创建唯一 Issue 并回填编号;领取时记录 context_ref、claim / 工作分支和全部允许写路径。

任何新增写路径先检查与其他活跃任务是否重叠;同一时刻只有一个 Agent 修改本任务的 write_paths。T-007 虽为 waiting,但写路径包含 Sense/;T-014 活跃期间不得恢复 T-007。

执行记录

2026-08-08 领取任务

  • dispatcher ila 将 Issue #47 分配给 codex;context_ref 为 8ebb8ced492c614106e766192c59b7f13fb4ad0f,claim 为 claims/T-014,工作分支为 agent/codex/T-014。
  • 已读回 Issue status/doing、assignee、dispatcher 发布的完整 CLAIM 与两个分支 SHA;接受 frontmatter 全部写路径。T-007 继续 waiting,本任务期间不恢复,当前无活跃写路径冲突。

2026-08-08 Gitea 映射

  • 任务规格通过 PR #46 合入默认分支后创建唯一主 Issue #47;本次只回填双向映射,映射合入并读回前不领取任务。

2026-08-08 任务定义

  • 项目负责人确认客户尚未提供网络环境,WireGuard T-013 后置;本任务先建立不依赖客户网络的本地 16 路软件基线。
  • 选择 PostgreSQL v5 + 真实 Control API,而不是沿用 SQLite 直接播种,确保实际覆盖 M2 的认证、配额、ETag、批量 operation、调和与 MediaMTX 路径。
  • 选择 16 个独立、预编码 -c copy 合成 publisher 作为正式可重复负载;T-006 已单独覆盖准入实机,本任务不混入公网摄像头波动,也不把合成结果表述为真实 16 机或生产 SLA。