284 lines
11 KiB
JSON
284 lines
11 KiB
JSON
{
|
|||
|
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||
|
|
"$id": "https://yovision.local/contracts/event-v0.1.schema.json",
|
||
|
|
"title": "YoVision Event Instance v0.1",
|
||
|
|
"description": "推理侧 → 平台侧的唯一契约。冻结于 2026-08-03。所有顶层键必须存在(可为 null),不允许省略——省略与显式 null 无法区分,是这类系统最常见的排查陷阱。",
|
||
|
|
"type": "object",
|
||
|
|
"additionalProperties": false,
|
||
|
|
|
||
|
|
"required": [
|
||
|
|
"schema_version",
|
||
|
|
"id",
|
||
|
|
"source_event_id",
|
||
|
|
"tenant_id",
|
||
|
|
"site_id",
|
||
|
|
"device_id",
|
||
|
|
"sensors",
|
||
|
|
"kind",
|
||
|
|
"severity",
|
||
|
|
"confidence",
|
||
|
|
"occurred_at",
|
||
|
|
"detected_at",
|
||
|
|
"latency_seconds",
|
||
|
|
"config_version",
|
||
|
|
"rule",
|
||
|
|
"subject",
|
||
|
|
"observation",
|
||
|
|
"evidence",
|
||
|
|
"dedup_key",
|
||
|
|
"aggregated_into",
|
||
|
|
"outcome",
|
||
|
|
"outcome_source",
|
||
|
|
"outcome_reason",
|
||
|
|
"diagnostics",
|
||
|
|
"ext"
|
||
|
|
],
|
||
|
|
|
||
|
|
"properties": {
|
||
|
|
"schema_version": {
|
||
|
|
"description": "契约版本。破坏性变更必须递增主版本。",
|
||
|
|
"const": "0.1"
|
||
|
|
},
|
||
|
|
|
||
|
|
"id": {
|
||
|
|
"description": "平台侧生成的全局唯一事件 ID(ULID)。推理侧不得自行生成。",
|
||
|
|
"type": "string",
|
||
|
|
"pattern": "^evt_[0-9A-HJKMNP-TV-Z]{26}$"
|
||
|
|
},
|
||
|
|
|
||
|
|
"source_event_id": {
|
||
|
|
"description": "推理侧原始事件 ID,如 silver_pose 的 FALL-<session>-000001。用于回溯本地截图文件名(截图即按它命名)。会话内唯一,全局不保证唯一——不得用作主键。",
|
||
|
|
"type": "string",
|
||
|
|
"pattern": "^[A-Za-z0-9_-]{1,128}$"
|
||
|
|
},
|
||
|
|
|
||
|
|
"tenant_id": { "type": "integer", "minimum": 1 },
|
||
|
|
"site_id": { "type": "integer", "minimum": 1 },
|
||
|
|
"device_id": {
|
||
|
|
"description": "主传感器的平台设备实体主键。由推理侧的 source_id 经平台映射表解析得到。事件中不得冗余 RTSP 地址或任何凭据。多传感器融合事件的完整来源见 sensors。",
|
||
|
|
"type": "integer",
|
||
|
|
"minimum": 1
|
||
|
|
},
|
||
|
|
|
||
|
|
"sensors": {
|
||
|
|
"description": "参与本次判定的全部传感器。单摄像头事件为单元素数组。恰好一个元素的 role 为 primary,且其 device_id 必须等于顶层 device_id。",
|
||
|
|
"type": "array",
|
||
|
|
"minItems": 1,
|
||
|
|
"items": {
|
||
|
|
"type": "object",
|
||
|
|
"additionalProperties": false,
|
||
|
|
"required": ["device_id", "modality", "role"],
|
||
|
|
"properties": {
|
||
|
|
"device_id": { "type": "integer", "minimum": 1 },
|
||
|
|
"modality": {
|
||
|
|
"description": "设备模态。决定隐私区域准入:privacy_flag 为真的区域只允许非成像模态。",
|
||
|
|
"type": "string",
|
||
|
|
"enum": ["video", "radar", "contact", "button", "wearable", "other"]
|
||
|
|
},
|
||
|
|
"role": {
|
||
|
|
"description": "primary=判定主依据;corroborating=佐证(如雷达判跌倒、门磁佐证无人离开)。",
|
||
|
|
"type": "string",
|
||
|
|
"enum": ["primary", "corroborating"]
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
},
|
||
|
|
|
||
|
|
"kind": {
|
||
|
|
"description": "事件类型。取值登记在 contracts/README.md 的类型注册表中,新增类型不需要升 schema 版本。v0.1 已登记:fall。",
|
||
|
|
"type": "string",
|
||
|
|
"pattern": "^[a-z][a-z0-9_]{2,63}$"
|
||
|
|
},
|
||
|
|
|
||
|
|
"severity": {
|
||
|
|
"type": "string",
|
||
|
|
"enum": ["low", "medium", "high", "critical"]
|
||
|
|
},
|
||
|
|
|
||
|
|
"confidence": {
|
||
|
|
"description": "模型置信度。几何+状态机判定链路没有天然来源,必须填 null——不得用任意常量或阈值余量伪造。",
|
||
|
|
"type": ["number", "null"],
|
||
|
|
"minimum": 0,
|
||
|
|
"maximum": 1
|
||
|
|
},
|
||
|
|
|
||
|
|
"occurred_at": {
|
||
|
|
"description": "事发时刻(墙钟 UTC)。决定证据回捞窗口。推理侧若只有单调时钟,按 detected_at - latency_seconds 换算。",
|
||
|
|
"type": "string",
|
||
|
|
"format": "date-time"
|
||
|
|
},
|
||
|
|
|
||
|
|
"detected_at": {
|
||
|
|
"description": "判定成立时刻(墙钟 UTC)。决定 SLA 计算。必须 >= occurred_at。",
|
||
|
|
"type": "string",
|
||
|
|
"format": "date-time"
|
||
|
|
},
|
||
|
|
|
||
|
|
"latency_seconds": {
|
||
|
|
"description": "从可疑到确认的耗时。可由两时间戳相减,但显式存储:它是判定质量的直接指标——贴近确认窗口下限说明证据干脆,贴近上限是误报高发区,为误报排查的首选排序键。",
|
||
|
|
"type": "number",
|
||
|
|
"minimum": 0
|
||
|
|
},
|
||
|
|
|
||
|
|
"config_version": {
|
||
|
|
"description": "产出本事件时整套判定配置的版本。粒度高于 rule.version(阈值往往是全局的),用于调参后的回归对比。不得为空串。",
|
||
|
|
"type": "string",
|
||
|
|
"minLength": 1,
|
||
|
|
"maxLength": 128
|
||
|
|
},
|
||
|
|
|
||
|
|
"rule": {
|
||
|
|
"description": "命中的规则实体。推理侧无规则引擎时为 null,由平台侧按 kind 反查补全。",
|
||
|
|
"type": ["object", "null"],
|
||
|
|
"additionalProperties": false,
|
||
|
|
"required": ["id", "version", "code"],
|
||
|
|
"properties": {
|
||
|
|
"id": { "type": "string" },
|
||
|
|
"version": { "type": "integer", "minimum": 1 },
|
||
|
|
"code": { "type": "string" }
|
||
|
|
}
|
||
|
|
},
|
||
|
|
|
||
|
|
"subject": {
|
||
|
|
"type": "object",
|
||
|
|
"additionalProperties": false,
|
||
|
|
"required": ["class", "track_id", "attributes", "anon_id", "identity", "identity_status"],
|
||
|
|
"properties": {
|
||
|
|
"class": { "type": "string", "enum": ["person", "vehicle", "object"] },
|
||
|
|
"track_id": {
|
||
|
|
"description": "跟踪器内的短期标识,跨会话不保证稳定。",
|
||
|
|
"type": "string",
|
||
|
|
"minLength": 1
|
||
|
|
},
|
||
|
|
"attributes": {
|
||
|
|
"description": "A 类属性(年龄段、着装等)。未启用时为空对象,不是 null。",
|
||
|
|
"type": "object"
|
||
|
|
},
|
||
|
|
"anon_id": {
|
||
|
|
"description": "B+ 类 ReID 匿名标识,站点内会话级有效(≤30min),不做跨日长期关联。未启用为 null。",
|
||
|
|
"type": ["string", "null"]
|
||
|
|
},
|
||
|
|
"identity": {
|
||
|
|
"description": "C 类人脸身份。仅在租户已授权且比对命中时非 null。",
|
||
|
|
"type": ["object", "null"],
|
||
|
|
"additionalProperties": false,
|
||
|
|
"required": ["person_id", "library_id", "score"],
|
||
|
|
"properties": {
|
||
|
|
"person_id": { "type": "string" },
|
||
|
|
"library_id": { "type": "string" },
|
||
|
|
"score": { "type": "number", "minimum": 0, "maximum": 1 }
|
||
|
|
}
|
||
|
|
},
|
||
|
|
"identity_status": {
|
||
|
|
"description": "必须显式。只写 null 无法区分「没开这功能」与「比对失败」,后者是需要排查的故障。",
|
||
|
|
"type": "string",
|
||
|
|
"enum": ["not_enabled", "pending", "matched", "below_threshold", "no_candidate", "timeout"]
|
||
|
|
}
|
||
|
|
}
|
||
|
|
},
|
||
|
|
|
||
|
|
"observation": {
|
||
|
|
"description": "结构化观测。bbox/keypoint 序列是数据闭环的唯一原料——只有视频与截图无法用于训练。",
|
||
|
|
"type": ["object", "null"],
|
||
|
|
"additionalProperties": false,
|
||
|
|
"required": ["zone", "dwell_sec", "bbox_seq_uri", "keypoint_seq_uri", "signal_seq_uri"],
|
||
|
|
"properties": {
|
||
|
|
"zone": { "type": ["string", "null"] },
|
||
|
|
"dwell_sec": { "type": ["number", "null"], "minimum": 0 },
|
||
|
|
"bbox_seq_uri": {
|
||
|
|
"description": "视觉模态专用。非视觉事件为 null。",
|
||
|
|
"type": ["string", "null"],
|
||
|
|
"format": "uri"
|
||
|
|
},
|
||
|
|
"keypoint_seq_uri": {
|
||
|
|
"description": "COCO-17 关键点逐帧序列(JSONL)。视觉模态专用,P1 必补项。",
|
||
|
|
"type": ["string", "null"],
|
||
|
|
"format": "uri"
|
||
|
|
},
|
||
|
|
"signal_seq_uri": {
|
||
|
|
"description": "非视觉模态的结构化序列(雷达点云轨迹与多普勒、门磁状态变迁等,JSONL)。与 keypoint_seq_uri 平级——两者是各自模态的数据闭环原料,缺任一模态的序列,该模态就无法参与模型迭代。",
|
||
|
|
"type": ["string", "null"],
|
||
|
|
"format": "uri"
|
||
|
|
}
|
||
|
|
}
|
||
|
|
},
|
||
|
|
|
||
|
|
"evidence": {
|
||
|
|
"type": "object",
|
||
|
|
"additionalProperties": false,
|
||
|
|
"required": ["snapshot_uris", "clip_uri", "clip_range"],
|
||
|
|
"properties": {
|
||
|
|
"snapshot_uris": {
|
||
|
|
"description": "证据截图。**允许为空数组**:非成像模态(雷达、门磁)产出的事件本就没有画面,隐私区域更是禁止成像。不得据此假设每个事件都有图可看——值班台 UI 必须能渲染无画面事件。文件命名只允许包含事件 ID 与日期目录,绝不得含 RTSP 地址、凭据或客户名称,文件名会出现在日志、URL 与工单中。",
|
||
|
|
"type": "array",
|
||
|
|
"minItems": 0,
|
||
|
|
"items": { "type": "string", "format": "uri" }
|
||
|
|
},
|
||
|
|
"clip_uri": {
|
||
|
|
"description": "含 pre-roll 的证据片段。仅有截图不足以让值班员判断真假,是误报反馈闭环的前置条件。P1 必补项。",
|
||
|
|
"type": ["string", "null"],
|
||
|
|
"format": "uri"
|
||
|
|
},
|
||
|
|
"clip_range": {
|
||
|
|
"type": ["array", "null"],
|
||
|
|
"minItems": 2,
|
||
|
|
"maxItems": 2,
|
||
|
|
"items": { "type": "string", "format": "date-time" }
|
||
|
|
}
|
||
|
|
}
|
||
|
|
},
|
||
|
|
|
||
|
|
"dedup_key": {
|
||
|
|
"description": "跨机位/跨时间去重键,由平台侧构造。推理侧进程内按 source_event_id 的去重仍保留——它防的是同帧重复写盘,属不同层次。",
|
||
|
|
"type": ["string", "null"]
|
||
|
|
},
|
||
|
|
|
||
|
|
"aggregated_into": {
|
||
|
|
"description": "被合并入的事件 ID。非 null 时本事件不独立触发告警。",
|
||
|
|
"type": ["string", "null"],
|
||
|
|
"pattern": "^evt_[0-9A-HJKMNP-TV-Z]{26}$"
|
||
|
|
},
|
||
|
|
|
||
|
|
"outcome": {
|
||
|
|
"description": "处置结果。事件不可变,误判只能通过本字段标记,不得删改。subject_recovered 由推理侧状态机自动回传(确认后自行起身),无需等人工。",
|
||
|
|
"type": "string",
|
||
|
|
"enum": [
|
||
|
|
"unknown",
|
||
|
|
"true_positive",
|
||
|
|
"false_positive",
|
||
|
|
"subject_recovered",
|
||
|
|
"duplicate",
|
||
|
|
"test"
|
||
|
|
]
|
||
|
|
},
|
||
|
|
|
||
|
|
"outcome_source": {
|
||
|
|
"type": ["string", "null"],
|
||
|
|
"enum": ["auto", "manual", null]
|
||
|
|
},
|
||
|
|
|
||
|
|
"outcome_reason": { "type": ["string", "null"] },
|
||
|
|
|
||
|
|
"diagnostics": {
|
||
|
|
"description": "推理侧内部诊断量,仅用于排查,平台不得依赖其语义。单调时钟跨进程无意义,不得用于任何时间计算。",
|
||
|
|
"type": ["object", "null"],
|
||
|
|
"additionalProperties": true,
|
||
|
|
"properties": {
|
||
|
|
"fsm_state": {
|
||
|
|
"type": "string",
|
||
|
|
"enum": ["NORMAL", "SUSPECT", "CONFIRMED", "RECOVERING"]
|
||
|
|
},
|
||
|
|
"suspected_at_monotonic": { "type": "number" },
|
||
|
|
"confirmed_at_monotonic": { "type": "number" },
|
||
|
|
"horizontal_angle_degrees": { "type": ["number", "null"] },
|
||
|
|
"visible_joint_count": { "type": ["integer", "null"], "minimum": 0, "maximum": 17 }
|
||
|
|
}
|
||
|
|
},
|
||
|
|
|
||
|
|
"ext": {
|
||
|
|
"description": "厂商/场景扩展位。根对象 additionalProperties=false,任何未登记字段一律放这里,避免为实验性字段升版本。",
|
||
|
|
"type": "object"
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|