Skip to content

Fix NamespaceExpose handling and improve top-level feature rendering#42

Merged
Malcolmnixon merged 4 commits into
mainfrom
bugfix/expose-scope-root-selection
Jul 16, 2026
Merged

Fix NamespaceExpose handling and improve top-level feature rendering#42
Malcolmnixon merged 4 commits into
mainfrom
bugfix/expose-scope-root-selection

Conversation

@Malcolmnixon

Copy link
Copy Markdown
Member

This pull request implements a new fallback behavior for Interconnection View layout in cases where the resolved expose scope does not name a single root definition, but instead directly includes one or more top-level part feature usages. Instead of rendering an empty canvas, these features are now rendered as "boxless" nodes side by side, with connections between them when appropriate. The changes include updates to documentation, requirements, and the core layout logic to support and explain this behavior, along with comprehensive test coverage.

Core Layout Logic and Behavior:

  • Added a "no-single-root scoped fallback" to InterconnectionViewLayoutStrategy, so when FindRoot finds no root but the scope includes top-level part feature usages, those features are rendered as boxless nodes side by side, recursing into their interiors as normal. This prevents valid diagrams from appearing empty when the scope names concrete features but not a root definition. ([[1]](https://github.com/demaconsulting/SysML2Tools/pull/42/files#diff-6348df1926db8d8e121df8483db2afaa47631be7d1f9401967af85b65eeac820L35-R92), [[2]](https://github.com/demaconsulting/SysML2Tools/pull/42/files#diff-fbfb8793b4fa4ef13a24da9593839e3770c507ce240ba736d6c0db8d8b68215bR44-R53))
  • Connections between these top-level boxless nodes are drawn if the connections themselves are in scope, ensuring relationships are not omitted. ([[1]](https://github.com/demaconsulting/SysML2Tools/pull/42/files#diff-6348df1926db8d8e121df8483db2afaa47631be7d1f9401967af85b65eeac820L35-R92), [[2]](https://github.com/demaconsulting/SysML2Tools/pull/42/files#diff-204c1372a24a23895102610db6cb3b977316ecedf9560a962602fddb53543ab0R254-R306))

Documentation and User Guide:

  • Updated the user guide and design documentation to describe the new fallback, including its motivation, behavior, and how it preserves existing empty-canvas results when no features are matched. ([[1]](https://github.com/demaconsulting/SysML2Tools/pull/42/files#diff-6348df1926db8d8e121df8483db2afaa47631be7d1f9401967af85b65eeac820L35-R92), [[2]](https://github.com/demaconsulting/SysML2Tools/pull/42/files#diff-a614960ca509ddd055be36ae4fea2a9b7716b47d293b5d32e83dd06a551d6f8eR240-R247), [[3]](https://github.com/demaconsulting/SysML2Tools/pull/42/files#diff-6348df1926db8d8e121df8483db2afaa47631be7d1f9401967af85b65eeac820L187-R248))
  • Added and clarified requirements and test scenario documentation for the fallback and its edge cases, including deduplication of nested features and connection rendering. ([[1]](https://github.com/demaconsulting/SysML2Tools/pull/42/files#diff-204c1372a24a23895102610db6cb3b977316ecedf9560a962602fddb53543ab0R254-R306), [[2]](https://github.com/demaconsulting/SysML2Tools/pull/42/files#diff-9ff2f7b125cdf16aa68140707d9d5e8fd38236aa4ede33e4e62c2ed596599023R30-R42), [[3]](https://github.com/demaconsulting/SysML2Tools/pull/42/files#diff-9ff2f7b125cdf16aa68140707d9d5e8fd38236aa4ede33e4e62c2ed596599023R101-R114), [[4]](https://github.com/demaconsulting/SysML2Tools/pull/42/files#diff-9ff2f7b125cdf16aa68140707d9d5e8fd38236aa4ede33e4e62c2ed596599023R144-R149))

Test Coverage:

  • Introduced dedicated tests for all fallback scenarios: rendering single and multiple top-level parts, recursing into container-typed features, drawing connections, excluding nested duplicates, and preserving the minimal canvas when appropriate. ([[1]](https://github.com/demaconsulting/SysML2Tools/pull/42/files#diff-9ff2f7b125cdf16aa68140707d9d5e8fd38236aa4ede33e4e62c2ed596599023R30-R42), [[2]](https://github.com/demaconsulting/SysML2Tools/pull/42/files#diff-9ff2f7b125cdf16aa68140707d9d5e8fd38236aa4ede33e4e62c2ed596599023R101-R114), [[3]](https://github.com/demaconsulting/SysML2Tools/pull/42/files#diff-9ff2f7b125cdf16aa68140707d9d5e8fd38236aa4ede33e4e62c2ed596599023R144-R149))

Expose Scope Logic:

  • Refined ExposeScopeResolver.IsRootRelevantToScope to correctly handle namespace-form expose scopes, ensuring that only appropriate candidates are considered root-relevant, in line with the SysML v2 specification. ([[1]](https://github.com/demaconsulting/SysML2Tools/pull/42/files#diff-2da9ff64798edd7056b162755f7abc04652cd79fb446f74f35ad742766d25079L248-R251), [[2]](https://github.com/demaconsulting/SysML2Tools/pull/42/files#diff-2da9ff64798edd7056b162755f7abc04652cd79fb446f74f35ad742766d25079R262-R272), [[3]](https://github.com/demaconsulting/SysML2Tools/pull/42/files#diff-2da9ff64798edd7056b162755f7abc04652cd79fb446f74f35ad742766d25079L270-R308))

Miscellaneous:

  • Added the term "boxless" to the cspell dictionary for documentation consistency. ([.cspell.yamlR33](https://github.com/demaconsulting/SysML2Tools/pull/42/files#diff-3eb548e27a9fd5527f6ea4dfe6350d3ecde8bcf4783f92658a2f5ae847a985fdR33))

These changes together ensure that Interconnection Views are rendered more faithfully to the SysML v2 specification, especially in cases where the exposed scope is more granular or namespace-like.

Malcolm Nixon and others added 4 commits July 16, 2026 11:21
…emantics

Per formal-26-03-02.md section 8.3.26.4, a NamespaceExpose (NamespaceRecursive /
NamespaceDirectChildren) exposes a namespace's Memberships, never the namespace
itself. IsRootRelevantToScope previously treated candidateQualifiedName == subject
as always root-relevant regardless of the subject's ExposeRecursionKind, causing
excluded subjects to still be drawn as the outer wrapping box in
asInterconnectionDiagram renders. Now the self-match direction is only honored for
MembershipRecursive/MembershipExact recursion kinds, which do include the subject
itself.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…tches

InterconnectionViewLayoutStrategy.FindRoot previously fell back to a totally
empty canvas whenever no single part def could be selected as the diagram
root, even when the resolved expose scope directly named one or more
concrete top-level part feature usages. This produced an empty diagram for
scopes like `expose Subsystem::*;` where Subsystem is a namespace-like part
def whose only nested content is a single part usage.

BuildLayout now falls back to collecting those top-level scoped part
features (CollectTopLevelScopedParts) and laying each out with the same
recursive container-vs-leaf logic already used by CollectParts, factored
out into BuildPartItem. Connections between the collected top-level
features are resolved via ResolveTopLevelConnections and drawn as before.
The features render side by side with no enclosing outer frame/title box.
LayOutInteriorWithConnections is parameterized with boxDepth and
reserveTitleArea so it can be reused for both the normal single-root
interior and this new flat top-level case. When the scope matches no
top-level feature either, the original empty-canvas fallback
(`new LayoutTree(200.0, 100.0, [])`) is preserved exactly.

Deviation from plan: BuildPartItem omits the ExposedScope? scope parameter
specified in the plan, since the original CollectParts always passed
scope: null to its recursive call regardless of its own scope argument,
making the parameter provably dead in the extracted method.

Adds 6 regression tests covering: the direct repro (single top-level
feature, no root def), two sibling top-level features arranged side by
side, a top-level feature that is itself a container (recurses into its
own interior), no matching feature (empty-canvas fallback preserved), a
connection drawn between two top-level features, and a nested feature
correctly excluded from top-level collection (not duplicated).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…outStrategy

Updates the three companion artifacts for the InterconnectionViewLayoutStrategy
feature that renders top-level exposed part features without a frame when no
single root definition is found:

- design doc: new remarks paragraph, new subsections for
  CollectTopLevelScopedParts/ResolveTopLevelConnections, BuildPartItem, and the
  parameterized LayOutInteriorWithConnections, plus an updated Error Handling
  section describing the new fallback path.
- reqstream yaml: three new requirement entries (ScopedTopLevelFeatureFallback,
  ScopedTopLevelFeatureFallbackConnections, ScopedTopLevelFeatureFallbackEmptyCanvas)
  linked to the new regression tests.
- verification doc: new verification-approach paragraph, acceptance criteria,
  and test-scenario table rows covering the new fallback.
- user guide: notes that an expose scope naming no root definition is no
  longer always an empty Interconnection View diagram when the scope directly
  includes top-level part feature usages instead.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add 'boxless' to .cspell.yaml words list next to 'frameless'
- Shorten 6 over-length (MD013 >120 chars) assertion cells in the
  interconnection-view-layout-strategy verification doc table, keeping
  test names and table structure unchanged

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@Malcolmnixon Malcolmnixon added the bug Something isn't working label Jul 16, 2026
@Malcolmnixon
Malcolmnixon merged commit 17933b1 into main Jul 16, 2026
9 checks passed
@Malcolmnixon
Malcolmnixon deleted the bugfix/expose-scope-root-selection branch July 16, 2026 17:24
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.

1 participant