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:
165
docs_v1.0/DESIGN/TKG_PHASE2_7_IDENTITY_RESOLUTION.md
Normal file
165
docs_v1.0/DESIGN/TKG_PHASE2_7_IDENTITY_RESOLUTION.md
Normal 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**
|
||||
|
||||
Reference in New Issue
Block a user