feat: Phase 2.7 identity resolution for gaze/lip trace nodes

Implementation:
- gaze_trace nodes: Query face_trace identity_id, add to properties
- lip_trace nodes: Query face_trace identity_id, add to properties
- Rule2: Extend identity resolution to support gaze_trace/lip_trace node types

Architecture:
- All face-related nodes now have identity_id in TKG properties
- Rule2 unified identity resolution for face_trace/gaze_trace/lip_trace
- TKG-only approach (no face_detections dependency for identity)

Code Changes:
- src/core/processor/tkg.rs: Add identity_id query in gaze/lip builders
- src/core/chunk/rule2_ingest.rs: Extend node_type condition

Docs:
- docs_v1.0/DESIGN/TKG_PHASE2_7_IDENTITY_RESOLUTION.md

Status: Implementation complete, pending test with valid file
This commit is contained in:
Accusys
2026-06-21 05:12:13 +08:00
parent 2cfcfdd1af
commit e214106d48
4 changed files with 265 additions and 11 deletions

View File

@@ -0,0 +1,165 @@
---
title: TKG Phase 2.7 Identity Resolution for Edges
version: 1.0
date: 2026-06-21
author: OpenCode
status: Draft
---
## Phase 2.7 Overview
为 gaze_trace 和 lip_trace nodes 添加 identity_id 属性,实现完整的 edge identity resolution。
## Current Implementation Analysis
### Rule2 Identity Resolution
**Location**: `src/core/chunk/rule2_ingest.rs`
**Current Logic** (lines 102-131):
```rust
// Only resolves face_trace nodes
let src_identity: Option<String> = if src_type == "face_trace" {
sqlx::query_scalar("SELECT i.name FROM tkg_nodes n
JOIN identities i ON i.id = (n.properties->>'identity_id')::bigint
WHERE n.node_type = 'face_trace' AND n.properties->>'identity_id' IS NOT NULL")
}
```
**Problem**:
- Only handles `face_trace` node type
- `gaze_trace` and `lip_trace` nodes lack identity_id
### Node Type Properties
| Node Type | external_id | identity_id | 状态 |
|-----------|-------------|-------------|------|
| **face_trace** | trace_{id} | ✓ 有 | ✅ Phase 2.3 |
| **gaze_trace** | gaze_{id} | ❌ 无 | 需要添加 |
| **lip_trace** | lip_{id} | ❌ 无 | 需要添加 |
## Solution Design
### Approach 1: Extend Rule2 Logic (Complex)
修改 Rule2 支持 gaze_trace/lip_trace node types
```rust
let src_identity: Option<String> = if src_type == "face_trace" || src_type == "gaze_trace" || src_type == "lip_trace" {
// Parse trace_id from external_id
let trace_id = src_ext_id.split('_').last()?;
// Query face_trace node
sqlx::query_scalar("SELECT i.name FROM tkg_nodes n
JOIN identities i ON i.id = (n.properties->>'identity_id')::bigint
WHERE n.node_type = 'face_trace' AND n.external_id = 'trace_' || $1")
.bind(trace_id)
}
```
**优点**: 不需要修改 TKG builders
**缺点**: Rule2 逻辑复杂,查询效率低
### Approach 2: Add identity_id in TKG Builders (Recommended)
在创建 gaze_trace/lip_trace nodes 时直接设置 identity_id
```rust
// Step 1: Query face_trace node's identity_id
let face_identity_id: Option<i64> = sqlx::query_scalar(
"SELECT (properties->>'identity_id')::bigint FROM tkg_nodes
WHERE file_uuid=$1 AND node_type='face_trace' AND external_id=$2"
)
.bind(file_uuid)
.bind(&format!("trace_{}", trace_id))
.fetch_optional(pool)
.await?;
// Step 2: Add to gaze/lip node properties
let props = serde_json::json!({
"trace_id": tid,
"identity_id": face_identity_id, // <-- NEW
...
});
```
**优点**:
- 性能最优(一次查询)
- Rule2 无需修改
- 逻辑清晰
**缺点**: 需要修改 TKG builders
### Recommended: Approach 2
## Implementation Plan
### Step 1: Modify build_gaze_trace_nodes_from_qdrant()
**Location**: `src/core/processor/tkg.rs:1859-1975`
**Add**:
```rust
// Query face_trace identity_id
let face_ext_id = format!("trace_{}", tid);
let face_identity_id: Option<i64> = sqlx::query_scalar(&format!(
"SELECT (properties->>'identity_id')::bigint FROM {}
WHERE file_uuid=$1 AND node_type='face_trace' AND external_id=$2",
nodes_table
))
.bind(file_uuid)
.bind(&face_ext_id)
.fetch_optional(pool)
.await?;
// Add to properties
let props = serde_json::json!({
"trace_id": tid,
"identity_id": face_identity_id, // <-- NEW
"frame_count": frame_count,
...
});
```
### Step 2: Modify build_lip_trace_nodes_from_qdrant()
**Location**: `src/core/processor/tkg.rs` (lip_trace builder)
**Add**: Same logic as gaze_trace
### Step 3: Update PostgreSQL fallback versions
Also update:
- `build_gaze_trace_nodes_from_pg()`
- `build_lip_trace_nodes_from_pg()`
### Step 4: Update Rule2 (Optional)
If desired, extend Rule2 to support gaze_trace/lip_trace:
```rust
let src_identity: Option<String> = if src_type == "face_trace" || src_type == "gaze_trace" || src_type == "lip_trace" {
// Query identity from node properties
...
}
```
**Note**: With Approach 2, Rule2 already works correctly!
## Verification Plan
1. TKG rebuild → check gaze/lip nodes have identity_id
2. Rule2 test → verify identity resolution works
3. Edge count comparison → ensure no regression
4. Performance benchmark → measure impact
## Success Criteria
- [ ] gaze_trace nodes have identity_id in properties
- [ ] lip_trace nodes have identity_id in properties
- [ ] Rule2 identity resolution works for all node types
- [ ] No regressions in edge counts
- [ ] Performance acceptable (<10ms added)
## Timeline
- Implementation: 1 day
- Testing: 0.5 day
- **Total: 1.5 days**