Skip to content

Commit 1352e1b

Browse files
committed
Merge branch 'worktree-self-improving-loops'
2 parents d232110 + f2aee96 commit 1352e1b

1 file changed

Lines changed: 10 additions & 5 deletions

File tree

graphcode/Sources/Features/App/AppSidebarView+Rows.swift

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -178,12 +178,17 @@ extension AppSidebarView {
178178
}
179179
}
180180

181-
/// This project's top-level rows — nodes nothing points at — in the human's
182-
/// arrangement (`sidebarNodeOrder`), not the graph's insertion order.
181+
/// This project's top-level rows, in the human's arrangement (`sidebarNodeOrder`).
182+
///
183+
/// `startAnchors`, not a bare "nodes nothing points at" filter — the difference is a
184+
/// bug this row tree had and the canvas never did: a closed cycle (a maker↔reviewer
185+
/// pair, forward edge one way, guarded back-edge the other) has no node without an
186+
/// inbound edge, so a walk from no-inbound roots alone dropped the whole cycle from
187+
/// the sidebar — two loops running, neither listed. `startAnchors` anchors each
188+
/// cycle-only component at its first node, and reusing it means the sidebar and the
189+
/// canvas can never again disagree about which nodes exist.
183190
func orderedRootNodes(in project: ProjectFeature.State) -> [LoopNode] {
184-
let roots = project.graph.nodes.filter { node in
185-
!project.graph.edges.contains { $0.to == node.id }
186-
}
191+
let roots = project.graph.startAnchors.compactMap { project.graph.nodes[id: $0] }
187192
let order = project.sidebarNodeOrder
188193
return roots.sorted { a, b in
189194
(order.firstIndex(of: a.id) ?? .max) < (order.firstIndex(of: b.id) ?? .max)

0 commit comments

Comments
 (0)