Skip to content

Fix routing of same-scope named-port edges and handle boundary-crossing#13

Merged
Malcolmnixon merged 1 commit into
mainfrom
fix/hierarchical-port-edge-drop
Jul 8, 2026
Merged

Fix routing of same-scope named-port edges and handle boundary-crossing#13
Malcolmnixon merged 1 commit into
mainfrom
fix/hierarchical-port-edge-drop

Conversation

@Malcolmnixon

Copy link
Copy Markdown
Member

This pull request addresses a previously undocumented but significant bug in the HierarchicalLayoutAlgorithm related to handling edges connected to named ports (LayoutGraphPort) within hierarchical graph layouts. The changes ensure that same-scope port edges are routed correctly and that unsupported boundary-crossing port edges now fail loudly with a clear exception. The documentation, requirements, and verification files have been updated to reflect and test these behaviors.

Bug Fixes and Routing Behavior

  • Same-scope port edge routing fixed: The algorithm now correctly routes edges whose endpoints are named ports belonging to direct members of the current scope, even if unrelated containers exist elsewhere in the scope. Previously, these edges were silently dropped; now, they are routed by the leaf algorithm as in a flat graph. [1] [2] [3] [4] [5] [6] [7]
  • Boundary-crossing port edges now throw: If a port edge genuinely crosses a container boundary, the algorithm throws a NotSupportedException with a clear message, rather than silently dropping the edge. This makes the limitation explicit and safer for users. [1] [2] [3]

Documentation and Requirements

  • Documentation updated: The design and roadmap documentation have been revised to explain the new behaviors for same-scope and boundary-crossing port edges, including the rationale and current limitations. [1] [2] [3]
  • Requirements and verification scenarios added: New requirements and verification scenarios have been introduced to specify and test the correct handling of same-scope port edges and the exception for boundary-crossing port edges. [1] [2] [3] [4]

Implementation Details

  • Internal data structures extended: The implementation now tracks port ownership and copies named ports into the internal view graph, ensuring correct routing and translation of port anchors during layout composition. [1] [2] [3] [4] [5]

…hrow on boundary-crossing port edges

- HierarchicalLayoutAlgorithm.ClassifyEdges previously silently dropped any
  edge with a LayoutGraphPort endpoint, even when the edge did not cross a
  container boundary, whenever the scope contained any container node
  elsewhere. This broke named-port support (Phase 1) as soon as any
  containment existed anywhere in the graph.
- Add portOwner map and TryResolveOwner helper to resolve port endpoints to
  their owning node for scope classification.
- Same-scope port edges (both endpoints direct members of current scope) are
  now routed normally through to LayeredLayoutAlgorithm, which already
  supports LayoutGraphPort endpoints via TryResolveEndpoint.
- Genuinely boundary-crossing port edges now throw a clear
  NotSupportedException instead of being silently dropped.
- BuildSizedView/TryMapConnectable carry Ports onto view nodes and remap
  leaf edge endpoints; LayoutScope extracts LayoutPort nodes from leaf
  output; Translate gained a LayoutPort case for correct nested-scope
  translation.
- Add 3 unit tests covering same-scope port routing, boundary-crossing
  exception, and nested container port translation.
- Update ROADMAP.md, design doc, verification doc, and reqstream yaml.
Copilot AI review requested due to automatic review settings July 8, 2026 22:17
@Malcolmnixon Malcolmnixon added the bug Something isn't working label Jul 8, 2026
@Malcolmnixon
Malcolmnixon merged commit bc2dec8 into main Jul 8, 2026
6 checks passed
@Malcolmnixon
Malcolmnixon deleted the fix/hierarchical-port-edge-drop branch July 8, 2026 22:18

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes a bug in HierarchicalLayoutAlgorithm where edges involving LayoutGraphPort endpoints were incorrectly dropped in hierarchical scopes, and formalizes unsupported boundary-crossing port-edge behavior by throwing a clear exception. This aligns hierarchical behavior with existing flat-graph port routing while making current limitations explicit across code, tests, requirements, and verification docs.

Changes:

  • Correctly classify and route same-scope named-port edges via the selected leaf algorithm, including copying named ports into the sized view graph.
  • Fail loudly for boundary-crossing named-port edges by throwing NotSupportedException instead of silently dropping.
  • Add regression tests plus requirements/design/verification documentation updates describing both behaviors.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
test/DemaConsulting.Rendering.Layout.Tests/HierarchicalLayoutAlgorithmTests.cs Adds regression tests for same-scope port routing, boundary-crossing port-edge exception, and port coordinate translation during composition.
src/DemaConsulting.Rendering.Layout/HierarchicalLayoutAlgorithm.cs Updates edge classification to resolve port ownership, copies ports into the sized view, includes emitted LayoutPorts in output, and translates ports during composition.
ROADMAP.md Documents the fixed bug and clarifies the interim “throw on boundary-crossing port edges” limitation pending Phase 2.
docs/verification/rendering-layout/hierarchical-layout-algorithm.md Extends verification scenarios and requirement-to-test mapping for same-scope port edges and boundary-crossing exceptions.
docs/reqstream/rendering-layout/hierarchical-layout-algorithm.yaml Adds new requirements covering same-scope port routing and boundary-crossing port-edge exception behavior.
docs/design/rendering-layout/hierarchical-layout-algorithm.md Updates design documentation to include port copying/routing behavior and the explicit exception for unsupported boundary-crossing port edges.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +578 to +580
const string boundaryPortMessage =
"Named ports on edges crossing a container boundary are not yet supported; see ROADMAP.md Phase 2.";

/// <param name="connectable">The edge endpoint to resolve.</param>
/// <param name="portOwner">Map from every descendant's named port to the node that owns it.</param>
/// <param name="owner">The resolved owning node, when resolution succeeds.</param>
/// <returns><see langword="true"/> when the endpoint resolves to a node in this scope's graph.</returns>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants