Skip to content

Variant-aware properties: per-variant field VALUES on a single artifact #255

@avrabe

Description

@avrabe

Problem

Today rivet has variant handling (feature model + variant config + binding model), but a single requirement cannot carry different field VALUES per variant. The motivating example: REQ-THERMAL-01.max-temp-c should be 80 in the automotive variant, 100 in industrial, 70 in consumer — same intent, same verification, same upstream stakeholder, just different numeric bounds.

Current workarounds (split into N artifacts, smuggle into description, reanchor on feature attributes) all damage traceability or break validation.

Design report

See docs/design/variant-aware-properties.md for the full report:

  • Today's state in rivet (where the gap is)
  • Competitor survey: Polarion, DOORS Next + pure::variants, sphinx-needs, FeatureIDE, Clafer, TVL
  • Academic context: Czarnecki, Apel et al., COVAMOF, Attributed Feature Models
  • Five candidate designs scored on validator complexity / dashboard / traceability / AI-friendliness / audit
  • Recommendation + YAML shape + worked examples + MVP scope + open questions

Recommendation (v1)

Add an optional fields-per-variant: map on every artifact — a flat BTreeMap<variant_name, BTreeMap<field_name, Value>> overlay on top of the existing fields: defaults:

- id: REQ-THERMAL-01
  type: requirement
  fields:
    max-temp-c: 80          # default / fallback
    min-temp-c: -20
  fields-per-variant:
    automotive: { max-temp-c: 80,  min-temp-c: -40 }
    industrial: { max-temp-c: 100, min-temp-c: -40 }
    consumer:   { max-temp-c: 70,  min-temp-c:   0 }

Resolution = merge(fields, fields_per_variant.get(active_variant)) — no new evaluator needed. Forward-compatible to expression-valued fields (option B in the doc) without schema rework.

MVP scope

  • Schema: fields-per-variant on Artifact, optional, default empty.
  • Validate: variant-key cross-check against binding model's variants:; per-field type-check identical to existing fields: validator.
  • API: Artifact::resolved_fields(variant: &str).
  • CLI: rivet show REQ-XXX --variant automotive, rivet validate --variant automotive.
  • Dashboard: variant selector + per-cell override marker.
  • Tests: dogfood pass updated to enumerate variant resolution; golden-file test for the motivating example.

Out of scope for v1: expression-valued fields, predicate-keyed overrides (multi-axis), exhaustiveness check, ReqIF/OSLC explode-on-export, SAT/SMT attribute calculations.

Single most important open question

Exclusive vs compositional override keys. Should each artifact field have exactly one applicable variant override (PV-style first-true-wins, simple to validate / render) or should multiple keys be allowed to apply simultaneously and merge in order (real PLE multi-axis: market × ASIL × cooling-class)? The answer determines whether v1's data shape is BTreeMap<name, …> or Vec<{ when, fields }>.

Trace

Refs: FEAT-001

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions