Skip to content

S-expression query language + product line engineering (variant management) #128

@avrabe

Description

@avrabe

Summary

Add a unified s-expression query/constraint language and a three-layer product line engineering (PLE) system for variant management. Inspired by pure::variants' architecture and informed by gaps identified in X-as-Code/Sphinx-Needs analysis.

Motivation

Safety-critical products ship in multiple configurations (market × safety level × feature set). Today rivet validates the union of all artifacts. There's no way to ask "is traceability complete for the EU + ADAS + ASIL-D variant specifically?" — a question auditors in automotive (ISO 26262), aerospace (DO-178C), and medical (IEC 62304) domains routinely ask.

External input

Architecture: Three-Layer Separation

Layer 1 — Feature Model (logical, problem space)

# feature-model.yaml
kind: feature-model
root: vehicle-platform
features:
  market: { group: alternative, children: [eu, us, cn] }
  safety-level: { group: alternative, children: [qm, asil-a, asil-b, asil-c, asil-d] }
  feature-set: { group: or, children: [base, adas, autonomous] }
constraints:
  - (implies eu pedestrian-detection)
  - (implies autonomous (and adas asil-d))

Layer 2 — Variant Configurations (specific products)

# variants/eu-adas-c.yaml
kind: variant
name: eu-adas-c
selects: [eu, adas, asil-c]
# Solver derives effective features, validates constraints

Layer 3 — Binding Model (implementation, solution space)

# bindings.yaml
kind: feature-binding
bindings:
  pedestrian-detection:
    artifacts: [REQ-042, REQ-043, SPEC-021]
    source: ["src/perception/pedestrian/**"]

S-Expression Language

One canonical syntax for all expressions — no sugar, no alternatives.

; CLI filtering
(and (= type "requirement") (has-tag "eu") (= status "approved"))

; Feature constraints
(implies autonomous (and adas asil-d))

; Traceability rules
(forall (where type "requirement")
  (exists (linked-by satisfies) (where type "specification")))

; Graph traversal
(reachable-from "REQ-001" satisfies)

Internally compiles to Datalog (guaranteed termination, incremental via salsa).

Key Design Decisions

  • DD-048: S-expressions as single canonical syntax (no infix sugar)
  • DD-049: Datalog semantics with termination guarantee (not Prolog)
  • DD-050: Three-layer PLE architecture (feature model / variant / binding)
  • DD-051: Thin custom Datalog evaluator over salsa (not datafrog/crepe)

Implementation Phases

Phase Features Artifacts
1 — Filter language S-expr parser, predicate evaluator, CLI --filter FEAT-106, FEAT-107, FEAT-108
2 — Datalog engine Compiler, semi-naive evaluator, s-expr traceability rules FEAT-109
3 — PLE core Feature model schema, constraint solver, binding model FEAT-110, FEAT-111, FEAT-112
4 — Variant validation Per-variant validate/coverage, variant-aware impact FEAT-113, FEAT-114

STPA Safety Analysis

7 hazards, 7 system constraints, 5 UCAs, 5 controller constraints, 4 loss scenarios documented in safety/stpa/variant-hazards.yaml.

Key hazards:

  • H-VAR-001: Variant validation passes but traceability gaps exist in deployed config
  • H-VAR-002: Feature model constraints don't capture real-world exclusions
  • H-VAR-003: Binding model drifts from artifacts without detection
  • H-VAR-004: S-expression evaluator bug produces wrong query results

Requirements

REQ-041 through REQ-046 in artifacts/requirements.yaml.

References

  • pure::variants (pure-systems GmbH) — industrial PLE with Prolog constraints
  • FODA — Feature-Oriented Domain Analysis
  • datafrog/Polonius — Datalog in Rust borrow checker
  • Sphinx-Needs needs_variants — simpler tag-based approach (comparison baseline)

🤖 Generated with Claude Code

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions