Skip to content

Commit f91ad20

Browse files
HumanBean17claude
andcommitted
add parent_edge_id to TraceEdge for lightweight tree reconstruction
Reviewed concern that flat edge list doesn't express hierarchy. Added parent_edge_id (nullable) to TraceEdge instead of full tree field. Seed edges have parent_edge_id: null; child edges reference the edge that reached their from_id. Enables O(1) tree reconstruction without duplicating node payloads. Full tree field deferred to v2 (#240). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
1 parent a8bebe1 commit f91ad20

1 file changed

Lines changed: 9 additions & 1 deletion

File tree

propose/active/TRACE-TOOL-PROPOSE.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ TraceEdge:
9090
to_id: str
9191
edge_type: str
9292
hop: int # BFS depth where discovered (0-indexed from seeds)
93+
parent_edge_id: str | None # ID of the incoming edge to from_id; null for seed edges. Enables tree reconstruction.
9394
collapsed: bool = False # true if this edge was produced by collapsing a trivial chain
9495
collapsed_intermediates: list[str] # node IDs of collapsed intermediates (empty if not collapsed)
9596
cross_service_boundary: bool = False # true if this edge crosses into another microservice (BFS stops here)
@@ -138,7 +139,9 @@ The trace engine is a **BFS traversal** that reuses the same Cypher query infras
138139
- Only followed when HTTP_CALLS/ASYNC_CALLS is in edge_types
139140
- Add Client/Producer node to frontier (needed to reach cross-service edge)
140141
- total_discovered += len(discovered neighbors)
141-
- Record TraceEdge(from=node, to=neighbor, hop=hop, attrs=...)
142+
- Record TraceEdge(from=node, to=neighbor, hop=hop, parent_edge_id=incoming_edge_id_for_node or None, attrs=...)
143+
- parent_edge_id: the ID of the edge that brought BFS to `node` (null for seed nodes at hop 0)
144+
- Enables O(1) tree reconstruction from flat edges without duplicating node payloads
142145
c. new_frontier = {neighbor.id for each discovered neighbor not in visited,
143146
excluding cross-service boundary downstream nodes}
144147
d. visited |= new_frontier
@@ -304,20 +307,23 @@ edges:
304307
to_id: "sym:OrderRepository#save"
305308
edge_type: "CALLS"
306309
hop: 1
310+
parent_edge_id: null # seed edge (or edge that reached OrderServiceImpl)
307311
cross_service_boundary: false
308312
attrs: {confidence: 1.0}
309313

310314
- from_id: "sym:OrderServiceImpl#createOrder"
311315
to_id: "client:PaymentClient"
312316
edge_type: "DECLARES_CLIENT" # auto-followed to reach HTTP_CALLS
313317
hop: 2
318+
parent_edge_id: null # same seed edge
314319
cross_service_boundary: false
315320
attrs: {}
316321

317322
- from_id: "client:PaymentClient"
318323
to_id: "route:payment-service:/api/payments:POST"
319324
edge_type: "HTTP_CALLS"
320325
hop: 3
326+
parent_edge_id: "DECLARES_CLIENT:OrderServiceImpl->PaymentClient" # edge that reached PaymentClient
321327
cross_service_boundary: true # BFS stops here
322328
attrs: {confidence: 0.85, strategy: "URI_PATH_MATCH", match: "exact", raw_uri: "/api/payments"}
323329

@@ -430,6 +436,8 @@ These questions were resolved during review (PR #234). Deferred items are tracke
430436

431437
10. **PR-TRACE-1 split** — **Split into PR-TRACE-1a (core BFS + budget + paths) and PR-TRACE-1b (pruning + collapsing + cross-service).** Core BFS correctness and pruning heuristics are different review surfaces.
432438

439+
11. **Flat edge list hierarchy** — **`parent_edge_id` on TraceEdge, not a full `tree` field.** A flat `edges` list requires agents to reconstruct the call tree from `from_id`/`to_id` pairs, which is cognitively expensive for 30+ edges. However, a full `tree` field duplicates structural data (tree nodes reference IDs in `nodes` dict, but the nesting itself is redundant with `from_id`/`to_id`). The lighter approach: each `TraceEdge` carries `parent_edge_id` (nullable, references the incoming edge to its `from_id`; null for seed edges). This is O(1) per edge, enables tree reconstruction when needed, and doesn't duplicate node payloads. A full nested `tree` field is deferred to v2 if agents demonstrate they need it — tracked in #240.
440+
433441
### Follow-up issues
434442

435443
- **#240** — trace tool: v2 enhancements (bidirectional traversal, richer collapse_trivial heuristic, configurable path ranking, configurable fan_out_cap ranking)

0 commit comments

Comments
 (0)