docs: define zone visualization engine workplan

This commit is contained in:
2026-05-24 17:56:40 +02:00
parent 5a2d987b6a
commit f41d0da831
2 changed files with 467 additions and 0 deletions

View File

@@ -0,0 +1,273 @@
# Zone Entity Visualization
## Intent
The graph explorer currently treats zones as visual overlays derived from node
metadata. That is useful for first orientation, but it keeps zones as a
decoration around an already-laid-out graph. The next step is to make a zone a
first-class visualization entity beside nodes and edges.
A zone is a bounded drawing surface for a subgraph. It is similar to a sheet of
paper or a layer in a graphics application: it decides which graph elements are
drawn inside it, how those elements are laid out, how it stacks with other
zones, and whether it can be collapsed into a representative node.
Zones are view entities. They help the operator inspect the fabric without
changing the underlying fabric graph. A zone can be based on deployment
environment, ownership, tenant boundaries, cost center, access zone, or any
other declared view rule, but those concepts remain distinct from the zone
mechanism itself.
## Core Model
A graph view contains three visible entity classes:
- nodes: fabric entities such as services, hosts, repos, scenarios, or owners
- edges: fabric relationships such as deployment, routing, ownership, policy,
dependency, or evidence links
- zones: visual drawing surfaces that contain a selected subgraph
A zone definition describes how to derive and render one zone. A zone instance
is the result of applying a definition to the current graph, filter state, and
view profile.
Zone definitions should be serializable so they can later live in saved graph
profiles, operator presets, or a dedicated view registry.
## Zone Definition
A zone definition should contain at least these fields:
```yaml
id: prod
label: Production
enabled: true
membership:
mode: include
rules:
- field: deploymentEnvironment
op: equals
value: prod
attraction:
rules:
- edge_type: fabric:serves
direction: both
depth: 1
node_filter:
field: kind
op: in
value: [service, endpoint]
layout:
algorithm: cose
options: {}
presentation:
height: 30
color: "#0f766e"
opacity: 0.16
blur_below: true
collapse:
enabled: true
label: Production Zone
```
The exact schema can evolve, but the responsibilities should stay separate:
- membership chooses seed nodes
- attraction optionally expands the zone from those seeds through selected edge
types and depths
- layout chooses how the zone subgraph is arranged
- presentation chooses how the zone itself is drawn and stacked
- collapse chooses how the zone can become a representative node
## Membership Rules
Membership rules decide which nodes initially belong to a zone. They should be
declarative and inspect node data rather than hard-code UI concepts.
Useful operators:
- `equals`
- `not_equals`
- `in`
- `not_in`
- `exists`
- `missing`
- `matches`
Useful rule composition:
- `all`: every nested rule must match
- `any`: at least one nested rule must match
- `none`: no nested rule may match
The first implementation can support a small subset such as `equals`, `in`,
`exists`, `all`, and `any`, then widen the rule language once saved zone
profiles need it.
## Attraction Rules
Attraction rules allow a zone to pull in additional nodes connected to the seed
set. This is useful when the operator wants a zone to include the services,
routes, machines, or contracts that make the zone understandable, even when
those nodes do not carry the seed attribute themselves.
An attraction rule should define:
- edge type or edge-type pattern
- direction: `out`, `in`, or `both`
- maximum depth
- optional node filter
- optional edge filter
Attraction must be deterministic. Given the same graph and zone definitions, the
same node should land in the same zone every time.
Attraction also needs a conflict policy because a node must not belong to more
than one zone. The recommended first policy is priority by zone height and then
definition order:
1. Seed membership wins over attracted membership.
2. If two zones seed the same node, the conflict is reported and the node is
assigned to the higher zone.
3. If two zones attract the same node, the node is assigned to the higher zone.
4. If height ties, the earlier definition wins.
5. Every conflict is recorded as a view diagnostic.
This keeps the single-zone invariant while making ambiguous rules visible.
## Single-Zone Invariant
A visible node must be assigned to zero or one zone in a given graph view. A node
that belongs to no zone remains on the base canvas.
The invariant is important because zones are meant to behave like drawing
surfaces, not like arbitrary tags. Allowing the same node to appear in multiple
zones would make edge routing, selection, collapse behavior, and interaction
state ambiguous.
The model can still support analytical overlap by reporting diagnostics and by
offering alternative view presets. It should not solve overlap by duplicating
nodes in the same rendered view.
## Zone Layout
Each zone may choose its own layout algorithm for its subgraph. For example:
- deployment zones may use force-directed layout
- ownership zones may use concentric layout
- stage zones may use grid layout
- collapsed or nearly empty zones may use compact deterministic placement
The outer graph layout and the zone subgraph layouts are separate concerns. A
first implementation can keep the current Cytoscape layout for all nodes and
only render zone surfaces around assigned nodes. A later implementation should
introduce a two-phase layout:
1. Place zones and unzoned nodes on the main canvas.
2. Place each zone's assigned subgraph inside that zone using the zone's layout.
This will likely require an internal view model that separates fabric graph data
from rendered graph coordinates.
## Layer Height And Overlap
Zone presentation includes a height. Height is a visual stacking concept, not a
security or ownership concept.
When zones overlap:
- higher zones should draw above lower zones
- lower zones may be desaturated when covered
- lower zones may be blurred or dimmed when covered
- labels should remain readable where practical
- pointer interaction should prefer the highest visible zone
The implementation should avoid implying that a higher zone is more important.
Height is about rendering order and view ergonomics only.
## Collapse To Zone Node
A zone can optionally collapse into a representative node. Collapsing is a view
operation that preserves graph connectivity:
- nodes inside the zone become hidden from the current view
- the zone node represents the collapsed zone
- edges between inside and outside nodes are reconnected to the zone node
- edges fully inside the zone are hidden or summarized
- expanding restores the original nodes and edges
The collapsed zone node should expose useful summary data:
- contained node count
- contained edge count
- dominant node kinds
- inbound and outbound boundary edge counts
- diagnostics such as membership conflicts
This enables drill-down exploration without destroying the operator's context.
## Hierarchical Zones
The collapse model naturally leads to hierarchical zones. A tenant subfabric may
sit inside a landlord fabric, an access zone may sit inside a deployment
environment, and a cost-center view may cut across both as an alternate profile.
Hierarchy should be introduced carefully:
- parent-child containment must be explicit in the zone definition or derived
from a deterministic rule
- a node still belongs to exactly one visible leaf zone
- collapsing a parent collapses all visible descendants
- cross-boundary edges must remain visible at the collapsed boundary
The first implementation should support flat zones. The data model should avoid
choices that would make hierarchy impossible later.
## Diagnostics
Zones should produce diagnostics because rule-based view construction can hide
important ambiguity.
Useful diagnostics:
- node matched by more than one membership rule
- node attracted by more than one zone
- edge crosses zone boundaries
- zone has no seed nodes
- attraction depth reached limit
- collapsed zone has hidden internal boundary evidence
Diagnostics belong to the visualization layer. They should not mutate the
fabric graph.
## Relationship To Fabric Concepts
Zones are not fabrics, subfabrics, realms, domains, environments, cost centers,
or tenants. A zone is a view mechanism that can visualize those concepts.
Examples:
- a deployment-environment zone groups nodes by `dev-tegwick`, `test`, or `prod`
- a financial fabric zone groups nodes by lord or tenant responsibility
- a cost-center zone groups nodes for accounting analysis
- an access-zone view groups nodes by operational access policy once that
metadata exists
This keeps the graph explorer flexible while preserving the stricter meaning of
fabric boundaries: who pays for, owns, and is responsible for infrastructure.
## Implementation Direction
The recommended path is incremental:
1. Introduce a pure zone resolver that converts graph data and zone definitions
into zone instances, node assignments, edge summaries, and diagnostics.
2. Replace the current hard-coded environment/access overlay derivation with
resolver-backed default zone definitions.
3. Add zone-aware rendering state to the graph explorer UI.
4. Add saved zone profiles once the model is stable.
5. Add collapse-to-zone-node behavior.
6. Add per-zone layout only after the resolver and rendering model are stable.
This order keeps the current useful overlay behavior while moving the engine
toward zones as first-class view entities.

View File

@@ -0,0 +1,194 @@
---
id: RAIL-FAB-WP-0022
type: workplan
title: "Promote graph zones to first-class visualization entities"
domain: railiance
repo: railiance-fabric
status: proposed
owner: codex
topic_slug: railiance-fabric
created: "2026-05-24"
updated: "2026-05-24"
---
# Promote Graph Zones To First-Class Visualization Entities
## Context
RAIL-FAB-WP-0021 introduced labeled zone boundary overlays in the graph
explorer. That gave the operator a useful visual grouping by deployment
environment and access zone, but the zones are still derived directly inside the
UI as overlay rectangles around already-rendered nodes.
The next direction is described in `docs/ZoneEntityVisualization.md`: zones
should become first-class visualization entities beside nodes and edges. A zone
is a drawing surface for part of the graph, with declarative membership rules,
optional attraction rules, rendering height, diagnostics, and eventually
collapse/drill-down behavior.
This workplan moves toward that model without forcing a large rewrite in one
step.
## Task 1: Define The Zone View Model
```task
id: RAIL-FAB-WP-0022-T01
status: todo
priority: high
```
Define an internal zone view model that can represent:
- zone definitions
- resolved zone instances
- node assignments
- edge summaries
- cross-zone boundary edges
- membership and attraction diagnostics
- presentation metadata such as label, color, and height
The model should be serializable enough to support saved graph profiles later,
but it does not need a persistence store in this task.
Expected result: a small typed model or schema with tests for construction and
basic serialization.
## Task 2: Implement A Pure Zone Resolver
```task
id: RAIL-FAB-WP-0022-T02
status: todo
priority: high
```
Implement a pure resolver that accepts graph nodes, graph edges, and zone
definitions, then returns resolved zone instances.
The first resolver should support a conservative rule subset:
- membership operators: `equals`, `in`, `exists`
- rule composition: `all`, `any`
- attraction by edge type, direction, and depth
- single-zone assignment invariant
- conflict diagnostics when rules overlap
Expected result: resolver unit tests that prove deterministic node assignment,
seed-vs-attraction precedence, conflict reporting, and depth-limited attraction.
## Task 3: Back The Existing Overlays With Zone Definitions
```task
id: RAIL-FAB-WP-0022-T03
status: todo
priority: high
```
Replace the graph explorer's hard-coded environment/access overlay grouping
logic with resolver-backed default zone definitions.
The current operator-facing behavior should remain available:
- deployment environment grouping renders `dev-tegwick`, `test`, and `prod`
- legacy `staging` evidence maps to `test`
- `all` is not rendered as a deployment environment zone
- access-zone grouping remains available when access-zone metadata exists
- visible nodes must be assigned to no more than one rendered zone
Expected result: existing graph explorer tests continue to pass, with new tests
showing that the UI obtains zone rectangles from resolved zone instances.
## Task 4: Add Zone Diagnostics To The Explorer
```task
id: RAIL-FAB-WP-0022-T04
status: todo
priority: medium
```
Expose zone resolver diagnostics in the graph explorer without overwhelming the
map.
Diagnostics should include at least:
- node matched by more than one zone
- node attracted by more than one zone
- zone definition produced no seed nodes
- attraction reached its configured depth limit
- edge crosses zone boundaries
Expected result: zone detail panels show scoped diagnostics, and tests verify
that diagnostics are generated by the resolver rather than ad hoc UI checks.
## Task 5: Persist Zone View Settings In Profiles
```task
id: RAIL-FAB-WP-0022-T05
status: todo
priority: medium
```
Extend saved graph profile state so profiles can remember zone configuration.
At minimum, preserve:
- whether zones are visible
- active zone definition set
- active zone grouping
- zone presentation preferences that are already supported by the UI
Expected result: saved views restore the same zone mode and default definition
set after reload.
## Task 6: Prototype Collapse-To-Zone-Node
```task
id: RAIL-FAB-WP-0022-T06
status: todo
priority: medium
```
Prototype collapsing a resolved zone into a representative node while preserving
external connectivity in the visible graph.
The prototype should:
- hide nodes assigned to the collapsed zone
- render a zone node with summary metadata
- reconnect external edges to the zone node for the current view
- hide or summarize internal edges
- expand back to the original view without data loss
Expected result: collapse behavior works for one zone at a time and is covered
by focused tests. Multi-zone hierarchy can remain future work.
## Task 7: Prepare For Per-Zone Layout
```task
id: RAIL-FAB-WP-0022-T07
status: todo
priority: low
```
Identify the UI and Cytoscape integration changes needed for each zone to use a
different layout algorithm for its assigned subgraph.
This task should not attempt a full layout rewrite unless the preceding tasks
make it small and safe. It should produce either a narrow implementation step or
a follow-up workplan for two-phase layout.
Expected result: the codebase has a documented path toward per-zone layouts
without destabilizing the current graph explorer.
## Acceptance Criteria
- Zone entity behavior is documented in `docs/ZoneEntityVisualization.md`.
- Zone definitions and resolved zone instances exist as explicit internal
concepts.
- The current deployment/access overlay behavior is implemented through the
zone resolver.
- The graph explorer keeps the single-zone assignment invariant for visible
nodes.
- Zone diagnostics are available to the operator.
- Saved graph views can preserve supported zone settings.
- Collapse-to-zone-node is prototyped behind clear UI behavior or an explicit
experimental switch.