phart

Style Rules Specification (v1.5, Implemented)

Status: Implemented in PHART v1.5.x (current branch behavior documented below). Audience: CLI users, library users, and maintainers

1. Problem Statement

PHART currently supports attribute-driven edge coloring via --edge-color-rule, but it is limited to direct edge-attribute equality matches. Users need richer conditions, including rules that combine edge attributes with endpoint node attributes (e.g. spouse edge color based on destination sex), while keeping simple cases ergonomic.

The design goal is a unified rule model that can style both nodes and edges without introducing multiple disconnected rule systems.

2. Goals

3. Non-Goals

4. Terminology

5. Canonical Rule Model

Rules normalize into this internal structure:

id: spouse-male
priority: 100 # optional integer; higher runs first
target: edge # edge | node | connector | panel_header
when: role == "spouse" and v.sex == "M"
set:
  color: blue # required field for color behavior

Notes:

Supported targets:

Supported set keys:

6. Expression Language (v1.5)

6.1 Operators

6.2 Literals

6.3 Attribute references

Resolution rules:

6.4 String comparison semantics

Default string comparisons are case-insensitive in v1.5 for compatibility with existing edge color rule normalization.

7. Rule Sources

7.1 CLI (simple)

Keep existing:

--colors attr --edge-color-rule parenttype:father=bright_blue,mother=bright_magenta

This is compiled into equivalent advanced rules at parse time.

7.2 CLI (advanced)

CLI supports repeated option:

--style-rule 'edge: role=="spouse" and v.sex=="M" -> color=blue'
--style-rule 'edge: role=="spouse" and v.sex=="F" -> color=green'

Optional file input for complex sets:

--style-rules-file rules.yaml

File format: YAML or JSON containing a rules array using canonical model.

7.3 Programmatic

LayoutOptions accepts raw canonical rule dicts via style_rules:

style_rules=[
    {
        "target": "edge",
        "when": 'role == "spouse" and v.sex == "M"',
        "set": {"color": "blue"},
    }
]

Implementation note:

8. Evaluation Semantics

  1. Build evaluation context for each element.
  2. Sort rules by:
    1. priority descending
    2. declaration order ascending
  3. Evaluate when for matching target.
  4. On match, apply keys in set not yet assigned.
  5. Continue until all rules checked (or short-circuit if all requested fields set).

v1.5 color behavior:

Fallbacks:

9. Backward Compatibility

Legacy mapping example:

--edge-color-rule role:spouse=blue

normalizes to:

- target: edge
  when: edge.role == "spouse"
  set: { color: blue }

10. Error Handling

11. Security and Safety

12. Performance Expectations

13. Implementation Status (Phased)

Phase 1 completed:

Phase 2 completed:

Phase 3 completed for current scope:

13.1 Phase 3 Expansion: Legacy Feature Convergence

Background

PHART has two historical styling tracks:

The style-rule system should become the canonical per-element styling mechanism, while preserving backward compatibility for existing global options.

Implemented rule-settable fields (v1.5)

Node-target fields:

Edge-target fields:

Precedence model (implemented)

  1. Engine defaults
  2. LayoutOptions explicit global values
  3. Style rules (priority + declaration order)

Style rules are last-write authority for the fields they set.

Compatibility strategy (implemented)

Constraints

13.2 Phase 3 Implementation Checklist

Execution board (feature branch: feature/style-rule-node-style):

ID Workstream Status Notes
A Contracts and option model Completed (Phase 3a) Key/target validation active for node:{color,prefix,suffix,node_style} and edge:{color,glyphs}
B Node rendering integration Completed (Phase 3a) Rule-driven prefix/suffix/node_style wired in shared node line resolution (layout + draw)
C Edge rendering integration Completed (Phase 3b) Rule-driven arrow_*, line_*, corner_*, tee_*, and cross integrated into routing/merge
D Legacy convergence path Completed (Decision) No implicit legacy-to-rule mapper in Phase 3; legacy globals remain, style-rules are authoritative
E CLI / UX surface Completed CLI/docs cover style-rules plus global edge presets/arrow modes
F Test plan In Progress Node-style + edge-glyph rule and validation tests added; parity tests pending
G Rollout sequencing Completed (Phase 3) Steps 1-5 complete for style-rule/node-style/edge-glyph scope

A. Contracts and option model

Acceptance criteria:

B. Node rendering integration

Acceptance criteria:

C. Edge rendering integration

Acceptance criteria:

D. Legacy convergence path

Acceptance criteria:

E. CLI / UX surface

Acceptance criteria:

F. Test plan (required before merge)

Acceptance criteria:

G. Rollout sequencing

  1. Validation + schema enforcement (implemented).
  2. Node rule fields (prefix/suffix/node_style) integration (implemented).
  3. Edge glyph fields integration (implemented).
  4. Legacy convergence decision + precedence finalization (implemented).
  5. Docs/examples finalization (implemented).

14. Test Matrix (Minimum)

15. Examples

Simple edge attr:

rules:
  - target: edge
    when: role == "parent" and parenttype == "mother"
    set: { color: bright_magenta }

Edge + endpoint attr:

rules:
  - target: edge
    when: role == "spouse" and v.sex == "M"
    set: { color: blue }
  - target: edge
    when: role == "spouse" and v.sex == "F"
    set: { color: green }

Node rule:

rules:
  - target: node
    when: sex == "F"
    set: { color: bright_magenta }