docs: update TKG, profile, identity module docs with trace management and external_id fix

- 15_tkg.md: external_id format changed to trace_N, added trace management section (delete/restore/merge)
- 18_profile.md: note external_id matching fix
- 07_identity.md: note bind/unbind external_id fix
- regenerated user docs (doc/)
This commit is contained in:
Accusys
2026-07-21 03:22:09 +08:00
parent 52bec30c90
commit 644516769c
7 changed files with 237 additions and 29 deletions
@@ -1102,4 +1102,5 @@ PATCH /api/v1/identity/:identity_uuid
This **replaces** the entire `aliases` array. To add to existing aliases, include all existing entries in the request.
---
*Updated: 2026-07-21 — Fixed bind/unbind TKG update to match both trace_N and face_track_N external_id formats*
*Updated: 2026-06-20 — Added identity files, chunks, faces, status, and JSON endpoints*
+99 -2
View File
@@ -14,7 +14,7 @@ TKG is a time-aligned knowledge graph built from multi-processor outputs (face,
| Node Type | External ID Format | Description | Key Properties |
|-----------|-------------------|-------------|----------------|
| `face_track` | `face_track_{trace_id}` | A tracked face identity over time | `trace_id`, `frame_count`, `status`, `pending_identity_name`, `confidence`, `identity_uuid` |
| `face_track` | `trace_{trace_id}` | A tracked face identity over time | `trace_id`, `frame_count`, `status`, `avg_bbox`, `avg_yaw`, `avg_pitch`, `avg_roll`, `start_frame`, `end_frame`, `pose_count` |
| `gaze_track` | `gaze_track_{id}` | Gaze direction over time | `direction` (frontal/left/right/up/down + diagonals) |
| `lip_track` | `lip_track_{id}` | Lip movement synced with speech | `speaker_id`, `lip_area_range` |
| `text_region` | `text_region_{id}` | Spoken text aligned to time | `speaker_id`, `text`, `start_time`, `end_time` |
@@ -426,4 +426,101 @@ curl -s "$API/api/v1/file/$FILE_UUID/processor-counts" \
---
*Updated: 2026-06-25 17:00:00*
### Trace Management
Endpoints for managing face traces: list, delete, restore, and merge.
#### `DELETE /api/v1/file/:file_uuid/trace/:trace_id`
**Auth**: Required
Soft-delete a face trace (default) or hard-delete with `{"hard_delete": true}`.
Soft delete marks Qdrant points with `status: "deleted"` and TKG nodes with `status: "deleted"` in properties. Deleted traces are excluded from the traces list.
Hard delete permanently removes Qdrant points and TKG nodes.
**Request Body** (optional):
| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `hard_delete` | boolean | `false` | Permanently delete instead of marking |
**Example**:
```bash
# Soft delete
curl -X DELETE "$API/api/v1/file/$FILE_UUID/trace/8" \
-H "X-API-Key: $KEY" -H "Content-Type: application/json" -d '{}'
# Hard delete
curl -X DELETE "$API/api/v1/file/$FILE_UUID/trace/8" \
-H "X-API-Key: $KEY" -H "Content-Type: application/json" \
-d '{"hard_delete": true}'
```
**Response**:
```json
{
"success": true,
"file_uuid": "9f6a9cd55a5809f977f5a6589b9045c5",
"trace_id": 8,
"hard_delete": false,
"qdrant_marked": true,
"tkg_nodes_marked": 1
}
```
---
#### `POST /api/v1/file/:file_uuid/trace/:trace_id/restore`
**Auth**: Required
Undo a soft-deleted trace. Clears `status: "deleted"` from Qdrant points and TKG node properties.
**Example**:
```bash
curl -X POST "$API/api/v1/file/$FILE_UUID/trace/8/restore" \
-H "X-API-Key: $KEY"
```
**Response**:
```json
{
"success": true,
"file_uuid": "9f6a9cd55a5809f977f5a6589b9045c5",
"trace_id": 8,
"qdrant_restored": true,
"tkg_nodes_restored": 1
}
```
---
#### `POST /api/v1/file/:file_uuid/trace/:source_trace_id/merge/:target_trace_id`
**Auth**: Required
Merge all face points from source trace into target trace. Updates Qdrant `trace_id` and deletes source TKG node.
**Example**:
```bash
curl -X POST "$API/api/v1/file/$FILE_UUID/trace/16/merge/3" \
-H "X-API-Key: $KEY"
```
**Response**:
```json
{
"success": true,
"file_uuid": "9f6a9cd55a5809f977f5a6589b9045c5",
"source_trace_id": 16,
"target_trace_id": 3,
"points_moved": 58,
"tkg_nodes_deleted": 1
}
```
---
*Updated: 2026-07-21 01:00:00*
@@ -264,4 +264,5 @@ curl -s -X PUT "$API/api/v1/file-profile" \
| `aliases` | `properties->'aliases'` | Multi-language name aliases |
---
*Updated: 2026-07-21 — Fixed external_id matching (trace_N + face_track_N formats), fixed parameter ordering in UPDATE query*
*Updated: 2026-07-18 — New profile module: trace-profile (GET, PUT, PUT group) and file-profile (GET, PUT)*
+27 -16
View File
@@ -310,34 +310,45 @@ curl<span class="w"> </span>-s<span class="w"> </span>-X<span class="w"> </span>
<td>6</td>
<td><code>face</code></td>
<td>—</td>
<td>Face detection &amp; embedding</td>
<td>Face detection &amp; embedding (8Hz sampling)</td>
</tr>
<tr>
<td>7</td>
<td><code>pose</code></td>
<td>—</td>
<td>Pose estimation</td>
<td><code>face_trace</code></td>
<td>face</td>
<td>Face tracking (IoU + embedding, assigns trace_id)</td>
</tr>
<tr>
<td>8</td>
<td><code>visual_chunk</code></td>
<td>yolo</td>
<td>Visual scene chunks</td>
<td><code>pose</code></td>
<td>face_trace</td>
<td>Pose expansion from face traces, inherits trace_id</td>
</tr>
<tr>
<td>9</td>
<td><code>story</code></td>
<td>asr, asrx, cut, yolo, face</td>
<td>Scene summaries (template)</td>
</tr>
<tr>
<td>10</td>
<td><code>5w1h</code></td>
<td>story</td>
<td>5W1H analysis (Gemma4 LLM)</td>
<td><code>appearance</code></td>
<td>pose</td>
<td>Appearance expansion from pose traces, inherits trace_id</td>
</tr>
</tbody>
</table>
<p><strong>Key Concepts:</strong>
- <strong>Face</strong> = Identity anchor (who is this person?) — requires high-quality embedding
- <strong>Pose</strong> = Tracking (where is this person?) — extends tracking when face is occluded
- <strong>Appearance</strong> = Tracking (what do they look like?) — extends tracking when pose is occluded</p>
<p><strong>Trace ID Inheritance:</strong></p>
<div class="codehilite"><pre><span></span><code><span class="n">Face</span><span class="w"> </span><span class="n">trace</span><span class="w"> </span><span class="p">(</span><span class="n">identity</span><span class="w"> </span><span class="err">anchor</span><span class="p">)</span>
<span class="w"> </span><span class="err">↓</span><span class="w"> </span><span class="n">inherits</span><span class="w"> </span><span class="n">trace_id</span>
<span class="n">Pose</span><span class="w"> </span><span class="n">expansion</span><span class="w"> </span><span class="p">(</span><span class="n">tracking</span><span class="w"> </span><span class="err">continuity</span><span class="p">)</span>
<span class="w"> </span><span class="err">↓</span><span class="w"> </span><span class="n">inherits</span><span class="w"> </span><span class="n">trace_id</span>
<span class="n">Appearance</span><span class="w"> </span><span class="n">expansion</span><span class="w"> </span><span class="p">(</span><span class="n">tracking</span><span class="w"> </span><span class="err">continuity</span><span class="p">)</span>
</code></pre></div>
<p><strong>Frame Count Relationship:</strong></p>
<div class="codehilite"><pre><span></span><code>face frames ≤ pose frames ≤ appearance frames
</code></pre></div>
<p>(Each level expands outward from the previous level's traces)</p>
<p>All processors except <code>story</code> and <code>5w1h</code> run concurrently when their dependencies are met. Story and 5W1H run sequentially after their prerequisites.</p>
<h4>Example</h4>
<div class="codehilite"><pre><span></span><code>curl<span class="w"> </span>-s<span class="w"> </span>-X<span class="w"> </span>POST<span class="w"> </span><span class="s2">&quot;</span><span class="nv">$API</span><span class="s2">/api/v1/progress/</span><span class="nv">$FILE_UUID</span><span class="s2">&quot;</span><span class="w"> </span>-H<span class="w"> </span><span class="s2">&quot;X-API-Key: </span><span class="nv">$KEY</span><span class="s2">&quot;</span><span class="w"> </span><span class="p">|</span><span class="w"> </span>jq<span class="w"> </span><span class="s1">&#39;{overall_progress, processors: [.processors[] | {name, status}]}&#39;</span>
+2 -1
View File
@@ -1738,7 +1738,8 @@ curl<span class="w"> </span>-s<span class="w"> </span>-X<span class="w"> </span>
<p>This <strong>replaces</strong> the entire <code>aliases</code> array. To add to existing aliases, include all existing entries in the request.</p>
<hr />
<p><em>Updated: 2026-06-20 — Added identity files, chunks, faces, status, and JSON endpoints</em></p>
<p><em>Updated: 2026-07-21 — Fixed bind/unbind TKG update to match both trace_N and face_track_N external_id formats</em>
<em>Updated: 2026-06-20 — Added identity files, chunks, faces, status, and JSON endpoints</em></p>
</div>
</body>
</html>
+90 -1
View File
@@ -100,7 +100,96 @@ a { color: #0066cc; }
</code></pre></div>
<hr />
<p><em>Updated: 2026-05-19 12:49:24</em></p>
<h3><code>POST /api/v1/agents/identity/confirm</code></h3>
<p><strong>Auth</strong>: Required
<strong>Scope</strong>: file-level</p>
<p>Confirm identity binding for a trace. This marks the trace as confirmed in TKG, updates face_detections, adds to _seeds, and optionally triggers Round 2 propagation.</p>
<h4>Request Parameters</h4>
<table class="table">
<thead>
<tr>
<th>Field</th>
<th>Type</th>
<th>Required</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>file_uuid</code></td>
<td>string</td>
<td>Yes</td>
<td>Video file UUID</td>
</tr>
<tr>
<td><code>trace_id</code></td>
<td>integer</td>
<td>Yes</td>
<td>Face trace ID to confirm</td>
</tr>
<tr>
<td><code>identity_id</code></td>
<td>integer</td>
<td>Yes</td>
<td>Identity internal ID</td>
</tr>
<tr>
<td><code>identity_uuid</code></td>
<td>string</td>
<td>Yes</td>
<td>Identity UUID</td>
</tr>
<tr>
<td><code>name</code></td>
<td>string</td>
<td>Yes</td>
<td>Identity name</td>
</tr>
<tr>
<td><code>propagate</code></td>
<td>boolean</td>
<td>No</td>
<td>Auto-trigger Round 2 matching (default: true)</td>
</tr>
</tbody>
</table>
<h4>Example</h4>
<div class="codehilite"><pre><span></span><code>curl<span class="w"> </span>-s<span class="w"> </span>-X<span class="w"> </span>POST<span class="w"> </span><span class="s2">&quot;</span><span class="nv">$API</span><span class="s2">/api/v1/agents/identity/confirm&quot;</span><span class="w"> </span><span class="se">\</span>
<span class="w"> </span>-H<span class="w"> </span><span class="s2">&quot;Authorization: Bearer </span><span class="nv">$JWT</span><span class="s2">&quot;</span><span class="w"> </span><span class="se">\</span>
<span class="w"> </span>-H<span class="w"> </span><span class="s2">&quot;Content-Type: application/json&quot;</span><span class="w"> </span><span class="se">\</span>
<span class="w"> </span>-d<span class="w"> </span><span class="s1">&#39;{&quot;file_uuid&quot;: &quot;&#39;</span><span class="s2">&quot;</span><span class="nv">$FILE_UUID</span><span class="s2">&quot;</span><span class="s1">&#39;&quot;, &quot;trace_id&quot;: 10, &quot;identity_id&quot;: 42, &quot;identity_uuid&quot;: &quot;&#39;</span><span class="s2">&quot;</span><span class="nv">$IDENTITY_UUID</span><span class="s2">&quot;</span><span class="s1">&#39;&quot;, &quot;name&quot;: &quot;Cary Grant&quot;, &quot;propagate&quot;: false}&#39;</span>
</code></pre></div>
<h4>Response (200)</h4>
<div class="codehilite"><pre><span></span><code><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;success&quot;</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;file_uuid&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;384b0ff44aaaa1f1&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;trace_id&quot;</span><span class="p">:</span><span class="w"> </span><span class="mi">10</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;identity_uuid&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;a9a90105...&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;name&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;Cary Grant&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;steps&quot;</span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;tkg_updated&quot;</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;qdrant_updated&quot;</span><span class="p">:</span><span class="w"> </span><span class="mi">150</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;pg_updated&quot;</span><span class="p">:</span><span class="w"> </span><span class="mi">150</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;seed_added&quot;</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span>
<span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="nt">&quot;propagation&quot;</span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;matched&quot;</span><span class="p">:</span><span class="w"> </span><span class="mi">5</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;message&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;Propagation completed&quot;</span>
<span class="w"> </span><span class="p">}</span>
<span class="p">}</span>
</code></pre></div>
<h4>Side Effects</h4>
<ol>
<li>TKG face_track node status → 'confirmed'</li>
<li>Qdrant _faces: identity_uuid added to payload</li>
<li>PG face_detections: identity_id set</li>
<li>Trace centroid added to _seeds (source='propagation')</li>
<li>Round 2 matching triggered (if propagate=true)</li>
</ol>
<hr />
<p><em>Updated: 2026-06-26 00:30:00</em></p>
</div>
</body>
</html>
+9 -1
View File
@@ -141,6 +141,12 @@ a { color: #0066cc; }
<td><code>chunk</code> table has rows with <code>chunk_type = 'sentence'</code></td>
</tr>
<tr>
<td>1.1</td>
<td><strong>Rule 1 OCR Chunks</strong></td>
<td>OCR done</td>
<td>OCR pre_chunks grouped into sentence chunks</td>
</tr>
<tr>
<td>2</td>
<td><strong>Auto-Vectorize</strong></td>
<td>Rule 1 done</td>
@@ -252,7 +258,9 @@ a { color: #0066cc; }
<div class="codehilite"><pre><span></span><code><span class="p">{</span>
<span class="w"> </span><span class="nt">&quot;file_uuid&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;bd80fec9c42afb0307eb28f22c64c76a&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="nt">&quot;steps&quot;</span><span class="p">:</span><span class="w"> </span><span class="p">[</span>
<span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nt">&quot;name&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;rule1_sentence&quot;</span><span class="p">,</span><span class="w"> </span><span class="nt">&quot;status&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;pending&quot;</span><span class="p">,</span><span class="w"> </span><span class="nt">&quot;detail&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;0 sentence chunks&quot;</span><span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nt">&quot;name&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;rule1_sentence&quot;</span><span class="p">,</span><span class="w"> </span><span class="nt">&quot;status&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;done&quot;</span><span class="p">,</span><span class="w"> </span><span class="nt">&quot;detail&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;35 sentence chunks&quot;</span><span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nt">&quot;name&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;rule1_ocr&quot;</span><span class="p">,</span><span class="w"> </span><span class="nt">&quot;status&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;done&quot;</span><span class="p">,</span><span class="w"> </span><span class="nt">&quot;detail&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;30 OCR frames&quot;</span><span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nt">&quot;name&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;rule1_ocr_chunks&quot;</span><span class="p">,</span><span class="w"> </span><span class="nt">&quot;status&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;done&quot;</span><span class="p">,</span><span class="w"> </span><span class="nt">&quot;detail&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;3 OCR-only chunks&quot;</span><span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nt">&quot;name&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;auto_vectorize&quot;</span><span class="p">,</span><span class="w"> </span><span class="nt">&quot;status&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;pending&quot;</span><span class="p">,</span><span class="w"> </span><span class="nt">&quot;detail&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;0 embedded&quot;</span><span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nt">&quot;name&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;rule3_scene&quot;</span><span class="p">,</span><span class="w"> </span><span class="nt">&quot;status&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;pending&quot;</span><span class="p">,</span><span class="w"> </span><span class="nt">&quot;detail&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;0 scene chunks&quot;</span><span class="w"> </span><span class="p">},</span>
<span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nt">&quot;name&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;face_trace&quot;</span><span class="p">,</span><span class="w"> </span><span class="nt">&quot;status&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;pending&quot;</span><span class="p">,</span><span class="w"> </span><span class="nt">&quot;detail&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;0 traces&quot;</span><span class="w"> </span><span class="p">},</span>