STIG Help

Elements and CREATE viewpoints

This tutorial series provides step-by-step guidance on using STIG to model and analyze safety‑critical systems — from early context definition through requirements, architecture/design, analysis, and test derivation.

The mental model is intentionally simple:

  • Your released product is a tree of Elements (clear, static building blocks — not “features”).

  • Every Element is documented using the same five CREATE viewpoints.

  • Viewpoints are connected via typed links, so you can navigate, refactor, and analyze change impact reliably.

Core principles

  1. Everything is expressed as a hierarchy of Elements.

  2. Elements are static building blocks (they are not features/functions) and have a clear definition.

  3. Element types form a containment chain: Vehicle → Item → SystemElement → Subsystem → Cluster → Component.

  4. Any released product is a tree of Elements.

  5. For each Element in your tree, you provide the following five CREATE viewpoints:

    1. Context – black‑box boundary, interfaces, external interactions, overview

    2. Requirements – black‑box “shall” statements

    3. Design – white‑box realization: decomposition, structure, behavior, interactions, allocations, and flow

    4. Analysis – e.g., FMEA, security, performance, timing

    5. Tests – tests derived from the viewpoints above

  6. All viewpoints can be captured in STIG by following its metamodel.

  7. The viewpoints can be developed by different people/teams, in parallel.

So in the end, every Element in your product tree is documented using the same five viewpoints. To keep the diagrams readable, the product tree and the viewpoints are shown separately below.

Element hierarchy vs. Gradle/Kotlin structure

STIG elements form a logical containment hierarchy, for example:

Vehicle
Item
SystemElement
Subsystem
Cluster
Component

SystemElement is the Highway type for a system; Subsystem is the next decomposition level.

That logical "part-of" structure is typically not reflected by the repository folder layout. Each element is owned and maintained as a package/module somewhere in a repository.

Therefore, to represent each Element of a product in Kotlin/Gradle project:

  • Each Element (Vehicle, Item, SystemElement, Subsystem, Cluster, Component) is represented as its own Kotlin module.

  • Modules can live anywhere in the repository folder tree, but element modules are not nested inside other element modules (each is a leaf).

  • Different elements map to different Kotlin modules.

Concept

Representation

Logical element containment

Parent links between elements in the Kotlin model

Element

One Kotlin/Gradle module (leaf)

Team ownership

Module location anywhere in the repo

Kotlin declaration layout

Use named classes at file scope for model entities that declare children. Keep child instances as properties of their owning entity: an Analysis owns InterfacePointAnalysis instances, and each InterfacePointAnalysis owns its Failure instances. Context owns the interface-point instances that Analysis references. Class nesting is not needed to express these relationships.

Put class definitions before the file's root instance properties. Prefix a child class name with its owning class name when generating it, for example Controller_OutputAnalysis; this distinguishes classes from different elements in the same Kotlin package. Every subclass of InterfacePointAnalysis ends in Analysis, using the interface-point name and an owner prefix when needed. Do not use Type for analysis wrappers. The generator omits the owner's redundant Analysis suffix, and puts collision numbers before the final suffix, for example Controller_Output2Analysis. Existing names that already end in Analysis remain stable. Use ordinary classes, without inner. A Kotlin object declaration is a singleton and does not provide a separate child instance for each owner. A public anonymous object exposes its declared supertype, so it cannot replace a named class when callers need its additional child properties.

Kotlin accepts val controller = Controller(). The KotlinPoet writer emits the explicit form val controller: Controller = Controller(). Both describe the same concrete property type. Preserve the concrete type of properties with children so references such as controllerAnalysis.output.missingOutput remain available.

Entity IDs include the declaring class and property name. Moving or renaming a class therefore changes the IDs of its member entities. Treat this as an identity migration: record the mapping, regenerate reports and exports, and verify references and any persisted review data that uses those IDs. A future builder DSL must preserve this identity and ownership contract and support both compiled loading and PSI materialization.

Product tree of Elements

Vehicle: Passenger Car

Item: Automated Driving

System: Camera

System: LiDAR

System: Radar

System: HPC

System: Power Braking System

Subsystem: RHIVOS Brain

Subsystem: Aurix Checker

Cluster: AUTOSAR CP

Cluster: Limiter Application

Component: OS

Component: RTE

This tree is your backbone: it’s the stable structure that everything else (requirements, interfaces, analyses, tests) attaches to.

Viewpoints for every Element

Element (any node in the tree)

five viewpoints

Context

Requirements

Design

Analysis

Tests

Relations across viewpoints

The key feature is linking: artifacts in any viewpoint can reference each other using typed relations (think: reliable code references, not fragile text pointers).

ASIL and severity comparisons

An element's asil states its development classification. Its optional allocatedAsil records the maximum ASIL of its allocated requirements, for example when those requirements are unavailable and their classification is lower than the element's. It is an authored declaration, not a cache. All element types support it. When requirements are available, STIG computes their maximum once across all requirement containers belonging to that element and checks it against both attributes.

Context, Requirements, Design, Analysis, InterfacePointAnalysis, Tests, and RequirementNote have no ASIL of their own. Their constructors do not accept asil; reading or overriding that property through one of those types is a Kotlin compilation error. Use the classified content instead. InterfacePoint.asil is the optional authored value; InterfacePoint.effectiveAsil resolves it through the definition and enclosing interface points, falling back to the owning element's asil. See Interface points. TestCase.asil remains available. A failure is bounded by failure.ownerInterfacePointAnalysis.interfacePoint.effectiveAsil.

For a classification bound a <= b, STIG applies this common reporting policy:

Comparison

Finding

Reported on

A contributor exceeds its bound (a > b)

HIGH violation

The entity holding a

The largest contributor equals the bound (max(a) == b)

No classification-difference finding

—

Every contributor is below the bound (max(a) < b)

INFO, for engineering review

The entity holding b

The maximum includes all contributors to the same bound for that relationship, including contributors in different containers. For an ASIL B interface, failures classified QM and A produce one INFO on the interface; failures classified QM and B produce none. A failure classified C produces HIGH on that failure. A lower individual contributor never produces an advisory when another contributor reaches the bound. Separate relationships, such as requirements and interfaces contributing to an element, are evaluated separately.

The comparisons apply as follows:

Viewpoint

Contributor a

Bound b

Context

element.allocatedAsil

element.asil

Context

Interface-point ASIL

Owning element's asil, and separately its non-null allocatedAsil

Requirements

Requirement ASIL

Subject element's ASIL

Requirements

Parent requirement ASIL (derivedFrom)

Derived requirement's ASIL

Design

Safety-mechanism ASIL

Owning element's ASIL

Analysis

Failure ASIL

Referenced interface point's ASIL

Analysis

Analysed interface-point ASIL

Parent interface-point ASIL through usedIn

Analysis

Source failure ASIL

Target failure ASIL through propagatesTo

Analysis

Source failure severity

Target failure severity through propagatesTo

For usedIn and failure propagation, the existing existential bound applies: at least one target must have a classification at least as high as the source. HIGH is reported on the source when every classified target is lower. The corresponding INFO is evaluated at each target against the maximum of its incoming contributors. For requirement derivation, HIGH therefore belongs to an excessive parent requirement, while INFO belongs to a derived requirement above all its parents. These checks do not model ASIL decomposition.

INFO requires a nonempty contributor set, known classifications for every contributor and the bound, and complete relevant model content. Empty, unknown, or incomplete sets do not establish overclassification. Missing required values, links, and context retain their own checks. ASIL order is QM < A < B < C < D.

There is one separate equality contract: if allocatedAsil is set and at least one requirement is available, the complete, classified requirement set must have max(requirement.asil) == element.allocatedAsil. A mismatch in either direction is HIGH on the element. Presence checks, fixed severity thresholds, and exact-equality checks do not gain a classification-difference advisory.

Classification advisories use INFO and SARIF informational, so they never fail a build, even with failAt = INFO. They carry no automatic downgrade fix; review whether the higher classification is justified. Disable all of these advisories with modelCheck { reportClassificationDifferences = false }; hard violations and unrelated information remain enabled. See the project-wide setting.

Relations between content within viewpoints

propagatesTo

Item: Automated Driving

System: Radar

Analysis with a failure mode — Radar generates points that do not exist in reality

Analysis with a failure mode — Unintended braking

This tree is your backbone: it’s the stable structure that everything else (requirements, interfaces, analyses, tests) attaches to.

That gives you practical advantages:

  • Immediate feedback: links are statically checked during editing/compilation, so broken references are caught early.

  • Refactor safely: rename/move things and let the tooling update references consistently (instead of “find & pray”).

  • Fast navigation: jump to definitions, find usages, and answer “where is this used?” quickly.

  • Change impact analysis: traverse links to see downstream effects — for example, an analysis failure mode on Radar can be linked as propagating to a higher-level failure on Automated Driving (see the propagatesTo relation in the diagram).

  • Consistency via properties: artifacts are not just text — they carry structured properties (e.g., IDs, owners, status, rationale, assumptions, safety relevance, verification method), which enables filtering, reporting, and review workflows.

In other words: the specification is a connected, queryable system model—not a stack of isolated documents.

23 October 2026