feat(etch): port-aware layout, orthogonal routing, interactive HTML#36
Closed
feat(etch): port-aware layout, orthogonal routing, interactive HTML#36
Conversation
Add recursive bottom-up Sugiyama layout for compound (hierarchical) graphs. Containers are sized to fit their children, with padding and header labels. SVG rendering draws containers as dashed-border background boxes with lightened fill colors. - NodeInfo gains `parent: Option<String>` for containment hierarchy - LayoutNode gains `is_container: bool` flag - LayoutOptions gains `container_padding` and `container_header` settings - layout() auto-detects compound graphs and delegates to layout_compound() - Variable-size node support in coordinate assignment - Container SVG: dashed border, bold header label, lightened fill - 8 new tests (6 layout + 2 SVG) covering 1-level, 2-level, sibling, mixed, and size constraint scenarios Trace: skip Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
petgraph 0.7 is API-compatible for our usage. Upgrading ensures downstream consumers (spar-render) don't need dual petgraph versions. Trace: skip Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Phase 3 workstream integration: - LSP server (rivet lsp) with diagnostics, hover, go-to-definition - SCORE metamodel schema (18 artifact types, ASPICE-aligned rules) - Kani proof harnesses (10 bounded model checking proofs) - Extended STPA safety analysis (H-9..H-15, SC-11..SC-17, 45 UCAs/CCs) - Extended AADL schema (4 artifact types) - Phase 3 design plans (6 workstream documents) Documentation and CI audit fixes: - Fix MSRV 1.85 → 1.89 in verification.md and clippy.toml - Fix schema type counts (ASPICE 14→13, Cybersecurity 10→8) - Add undocumented modules to architecture.md (lsp, proofs, embedded, externals, lifecycle, commits, docs, schema_cmd) - Replace missing .github/actions/compliance with inline steps - Standardize checkout@v6 → v4 across release workflow - Add anti-pattern guidance: do not hardcode counts in documentation - Fix FEAT-050/051 phase-4 → future (schema validation warning) - Add FEAT-052 (LSP) and FEAT-053 (SCORE schema) artifacts - Remove stale hardcoded artifact counts from getting-started.md - Fix clippy collapsible_if and map_entry warnings - Fix pre-commit hooks: +stable for clippy, remove invalid --strict flag - cargo fmt clean, 216 tests pass, validate PASS (0 warnings) Implements: FEAT-052 Implements: FEAT-053 Implements: FEAT-049 Refs: REQ-007 Refs: REQ-010 Refs: REQ-030 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
10-task plan covering: - Reusable UI components (filter bar, sortable table, collapsible tree, pagination) - serve.rs split into serve/ module directory - URL-persisted view state across all views - Graph scalability (spawn_blocking, node budget, dynamic SVG buffer) - Rich STPA/traceability views with fold/unfold and link drill-down - Print mode (?print=1) for clean printable output - Comprehensive Playwright E2E test suite (16 spec files) - STPA scalability coverage (H-13, SC-15) - CI integration for Playwright Refs: FEAT-052 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Dashboard graph view can become unresponsive when artifact count exceeds the Sugiyama layout engine's capacity. H-13 captures this as a hazard leading to L-4 (productivity) and L-5 (safety assurance). SC-15 requires graceful degradation with node budgets and spawn_blocking. UCA-D-3 and CC-D-3 constrain the dashboard controller. Refs: H-13 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Extract monolithic serve.rs into 5 focused files: - mod.rs (934 lines) — AppState, router, middleware, utility handlers - styles.rs (580 lines) — CSS constant - js.rs (1027 lines) — GRAPH_JS, SEARCH_JS, AADL_JS constants - layout.rs (200 lines) — page_layout() with CSS/JS imports - views.rs (4846 lines) — all 30+ view handlers and param structs No behavioral changes. All routes, HTML output, and tests identical. Implements: FEAT-052 Refs: DD-005 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…alysis REQ-037 through REQ-042: source-code traceability scanning, artifact revision staleness, deep recursive coverage, variant/product-line filtering, overlay files, and structured export for external viz tools. All draft status with upstream-ref noting competitive origin. Implements: REQ-004 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…amic SVG buffer - Add max_nodes budget to LayoutOptions; returns sentinel node when exceeded - Move graph layout + SVG render to tokio::spawn_blocking (unblocks async runtime) - Dynamic SVG String capacity (~500 bytes/node + ~200 bytes/edge) - Default budget: 300 nodes, configurable via ?budget=N (max 1000) - Pre-collect owned NodeInfo before spawn_blocking (Send + 'static) Fixes: H-13 Implements: SC-15 Implements: CC-D-3 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
FEAT-054: rivet add --link (create with links in one command) FEAT-055: rivet batch (apply multiple mutations from file) FEAT-056: JSON output for validate/coverage/context/diff FEAT-057: rivet graph <id> --depth N (local link neighborhood) FEAT-058: rivet scaffold --chain (generate traceability skeleton) From intensive AI agent testing session — the theme is: reduce round-trips (batch operations, links-on-create) and produce machine-readable output (JSON everywhere) for agent workflows. Refs: REQ-031 Refs: REQ-042 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add port-aware types to etch's public API: - PortInfo, PortSide, PortDirection, PortType — define ports on nodes - LayoutPort — positioned port in layout output - NodeInfo gains `ports: Vec<PortInfo>` (empty = backward compat) - EdgeInfo gains `source_port`/`target_port: Option<String>` - LayoutNode gains `ports: Vec<LayoutPort>` - LayoutEdge gains `source_port`/`target_port: Option<String>` All existing callers (rivet, etch tests) updated with empty ports. 40 tests pass, full backward compatibility preserved. Satisfies: RENDER-REQ-002 Trace: skip Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- position_ports() computes LayoutPort coordinates from PortInfo + node bounds - PortSide::Auto resolves In→Left, Out/InOut→Right - Node height grows for port count (12px/port + 8px padding) - Edge waypoints snap to port (x,y) when source_port/target_port set - 4 new tests: side positioning, auto resolution, height growth, edge snapping Satisfies: RENDER-REQ-002 Trace: skip Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
New components.rs module with: - ViewParams: URL query param struct shared across all views (types, status, tags, q, sort, dir, page, per_page, open, print) - FilterBar: type checkboxes, status dropdown, text search with HTMX debounce (300ms), all wired to URL params - SortableTable: clickable column headers toggle sort direction in URL - CollapsibleTree: <details>/<summary> with URL-persisted open IDs, Expand All / Collapse All buttons - Pagination: page controls with « ‹ N of M › » navigation - paginate() helper for slicing data by page Also fixes etch port fields (ports, source_port, target_port) added by spar integration work — updates all NodeInfo/EdgeInfo constructors in serve views and etch tests. 12 unit tests for all components. Implements: FEAT-052 Refs: DD-005 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Port circles, direction triangles, labels, and CSS type classes. Satisfies: RENDER-REQ-002 Trace: skip Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- FilterBar with 10 STPA type checkboxes + UCA subtype dropdown - URL-persisted fold state (?open=H-1,H-2,...) — defaults to losses+hazards open - Expand All / Collapse All buttons updating URL - Type filtering (?types=loss,hazard) for both hierarchy and UCA table - Text search (?q=firmware) across ID and title, case-insensitive - UCA subtype filter (?status=not-providing) for tree and table - Empty-state messages when filters yield no results Implements: FEAT-052 Refs: REQ-002 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
EdgeRouting::Orthogonal (default) and CubicBezier (legacy). New LayoutOptions fields: bend_penalty, edge_separation, port_stub_length. Orthogonal falls back to CubicBezier until ortho.rs is implemented. Satisfies: RENDER-REQ-001 Trace: skip Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- print_layout() renders content without nav, context bar, HTMX, or JS - Print CSS: hides interactive elements, sets max-width, @media print - Middleware detects ?print=1 query param and uses print_layout - Print button added to context bar (opens current URL + ?print=1 in new tab) - Works on all routes: /stpa?print=1, /artifacts?print=1, etc. Implements: FEAT-052 Refs: DD-005 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
New ortho.rs module implements visibility-graph-based orthogonal router: - Padded obstacle rectangles from all nodes - A* pathfinding with bend penalty on candidate waypoints - Direct routing for axis-aligned pairs, L-shaped fallback - 5 new tests (direct, L-shaped, obstacle avoidance, multi-node) Layout dispatches on EdgeRouting::Orthogonal vs CubicBezier. Satisfies: RENDER-REQ-001 Trace: skip Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Detect axis-aligned waypoints and emit L (line-to) commands instead of C (cubic bezier). Non-orthogonal paths still use bezier curves. Trace: skip Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ination - FilterBar with type checkboxes, status dropdown, text search - SortableTable with clickable column headers (ID, Type, Title, Status, Links) - Pagination (default 50/page) with URL-persisted page state - All filter/sort/page state in URL: /artifacts?types=requirement&sort=id&dir=asc&page=2 - Removed old client-side filterTable() JS — server-side filtering replaces it Implements: FEAT-052 Refs: DD-005 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
New html module wraps SVG in self-contained HTML with embedded JS: - Pan: click-drag on background - Zoom: mouse wheel around cursor, viewBox manipulation - Selection: click node to select, Ctrl+click for multi-select - Group highlight: click container to select - CustomEvent emission (etch-select, etch-container-select) - URL parameter ?highlight=ID for deep linking - Semantic zoom CSS classes (zoom-low, zoom-overview) - 5 new tests Satisfies: RENDER-REQ-003, RENDER-REQ-005, RENDER-REQ-006 Trace: skip Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Major etch rendering upgrade with three new capabilities:
Port-aware layout (RENDER-REQ-002)
PortInfo,PortSide,PortDirection,PortTypedata modelsource_port/target_portsetOrthogonal edge routing (RENDER-REQ-001)
ortho.rsmodule with visibility-graph-based A* routerEdgeRouting::Orthogonal(default) vsCubicBezier(legacy)L(line-to) commands for orthogonal pathsInteractive HTML wrapper (RENDER-REQ-003, 005, 006)
html.rsmodule producing self-contained HTML?highlight=IDfor deep linkingBackward compatibility
NodeInfo::portsdefaults to empty vecEdgeInfo::source_port/target_portdefault toNoneTrace: skip
🤖 Generated with Claude Code