STIG Help

Highway model rules

These rules check Highway models across the CREATE viewpoints. This catalog is generated from DefaultRules.all, the same Kotlin definitions used by Gradle and IDEA.

There are 126 automatic checks and 23 human or AI review rules (149 rules in total). Select a rule ID in either index to read its definition and corrective action below. Each section keeps the existing Kotlin-defined rule ID as its link anchor. Severity badges list every severity the Kotlin check can emit. They are finding severities, not model ASILs. Semantic checks emit INFO review records; their default violation severity applies to the reviewed contract.

Dispatch input is not the complete review scope. Inventory rules select the subjects described by their contracts. Complete model scope means all project model outputs were loaded; it does not establish that external standards, needs, budgets, or other engineering evidence are available.

Automatic checks

Gradle and IDEA evaluate these rules automatically and report violations.

Rule ID

Name

Possible finding severities

nonContextEntityInContextPackage

Entity uses the wrong viewpoint package (Context)

HIGH

contextClassesTopLevel

Context class is nested inside another declaration

MODERATE

contextClassInstance

Context class has no instance property in its file

MODERATE

contextClassPascalCase

Context class name violates PascalCase

MODERATE

contextObjectCamelCase

Context instance name violates camelCase

MODERATE

nameDefinedInContextPackage

Context entity has no required name

HIGH

descriptionDefinedInContextPackage

Context entity has no required description

HIGH

elementAsilDefined

Element has no ASIL

HIGH

forbiddenWordsInContext

Context entity contains forbidden wording

MODERATE

elementAllocatedAsilBound

Element allocates an ASIL above its own ASIL

HIGH INFO

interfacePointAsilBound

Provided interface point exceeds its element's ASIL limit

HIGH INFO

interfacePointParentAsilBound

Interface point exceeds its enclosing interface point's ASIL

HIGH

elementParentDefined

Element has no required parent

HIGH

elementTopLevelNoParent

Top-level element declares a parent

MODERATE

elementInParentDesign

Element names a parent whose design omits it

HIGH

interfaceEntityAsilDefined

Context entity has no required ASIL

HIGH

portMemberUse

Port member use references a member outside its service interface

HIGH

portMemberUseAsilBound

Port member use exceeds its referenced member's ASIL

HIGH

requiredMethodDefinitionAsilBound

Required method exceeds its definition's ASIL

HIGH

unresolvedInterfaceMember

Service member has no resolved interface definition

HIGH

requirementMustLiveInRequirementContainer

Requirement lacks a containing requirements specification

HIGH

nonRequirementsEntityInRequirementsPackage

Entity uses the wrong viewpoint package (Requirements)

HIGH

requirementsClassesTopLevel

Requirements class is nested inside another declaration

MODERATE

requirementsClassInstance

Requirements class has no instance property in its file

MODERATE

requirementsClassPascalCase

Requirements class name violates PascalCase

MODERATE

requirementsObjectCamelCase

Requirements instance name violates camelCase

MODERATE

nameDefinedInRequirementsPackage

Requirements entity has no required name

HIGH

descriptionDefinedInRequirementsPackage

Requirements entity has no required description

HIGH

requirementAsilDefined

Requirement has no ASIL

HIGH

requirementVerificationCriteriaDefined

Requirement has no verification criteria

HIGH

requirementContainerElementDefined

Requirements specification has no subject element

HIGH

requirementContainerSubject

Requirement names a different subject from its specification

HIGH

requirementNormativeModal

Requirement omits a recognized normative modal

MODERATE

subjectBeforeVerbInRequirement

Requirement omits its subject before the normative modal

MODERATE

forbiddenWordsInRequirement

Requirements entity contains forbidden wording

MODERATE

requirementAllocation

Requirement has no subject element

HIGH

requirementAllocatedToDefined

Requirement allocates to no child element

HIGH

requirementBottomLevelNoAllocation

Bottom-level requirement allocates to child elements

MODERATE

requirementAllocationCoverage

Requirements omit an allocated obligation

HIGH

requirementAllocatedToChildOfSubject

Requirement allocates outside its subject's design children

HIGH

designChildAllocation

Parent requirements omit allocation to a design child

HIGH

orphanRequirement

Derived requirement cites no parent requirement

HIGH

requirementAsilLeqSubject

Requirement exceeds its subject element's ASIL

HIGH INFO

requirementAsilDerivation

Derived requirement falls below a parent requirement's ASIL

HIGH

requirementAsilOverclassification

Derived requirement exceeds every parent requirement's ASIL

INFO

requirementDerivedFromAllocationConsistency

Requirement derives from a parent that does not allocate to its subject

HIGH

requirementTopLevelNoParent

Top-level requirement cites a parent requirement

MODERATE

safetyMeasureMustLiveInDesign

Safety measure lacks a containing design

HIGH

nonDesignEntityInDesignPackage

Entity uses the wrong viewpoint package (Design)

HIGH

designClassesTopLevel

Design class is nested inside another declaration

MODERATE

designClassInstance

Design class has no instance property in its file

MODERATE

designClassPascalCase

Design class name violates PascalCase

MODERATE

designObjectCamelCase

Design instance name violates camelCase

MODERATE

nameDefinedInDesignPackage

Design entity has no required name

HIGH

descriptionDefinedInDesignPackage

Design entity has no required description

HIGH

designElementDefined

Design has no subject element

HIGH

safetyMechanismAsilDefined

Safety mechanism has no ASIL

HIGH

safetyMeasureAsilDefined

Safety measure has no ASIL

HIGH

forbiddenWordsInDesign

Design entity contains forbidden wording

MODERATE

safetyMechanismAsilExceedsElement

Safety mechanism exceeds its element's ASIL

HIGH INFO

designChildrenParent

Design lists a child with a different parent

HIGH

designChildrenBoundary

Design contradicts the element's bottom-level declaration

HIGH

failureMustLiveInInterfacePointAnalysis

Failure lacks a containing interface-point analysis

HIGH

interfacePointAnalysisMustLiveInElementAnalysis

Interface-point analysis lacks a containing element analysis

HIGH

nonAnalysisEntityInAnalysisPackage

Entity uses the wrong viewpoint package (Analysis)

HIGH

analysisClassesTopLevel

Analysis class is nested inside another declaration

MODERATE

analysisClassInstance

Analysis class has no instance property in its file

MODERATE

analysisClassPascalCase

Analysis class name violates PascalCase

MODERATE

analysisObjectCamelCase

Analysis instance name violates camelCase

MODERATE

interfacePointAnalysisName

Analysis declaration violates the Analysis naming convention

MODERATE

nameDefinedInAnalysisPackage

Analysis entity has no required name

HIGH

descriptionDefinedInAnalysisPackage

Analysis entity has no required description

HIGH

analysisElementDefined

Analysis has no subject element

HIGH

analysisQmAssessment

Analysis omits the assessment for its QM exemption

HIGH

interfacePointAnalysisQmAssessment

Interface-point analysis omits the assessment for its QM exemption

HIGH

interfacePointAnalysisScopeAssessment

Interface-point analysis omits the assessment for its safety-scope exclusion

HIGH

failureAsilDefined

Failure has no ASIL

HIGH

failureSeverityDefined

Failure has no severity

HIGH

failureMultiplicityDefined

Failure has no multiplicity

HIGH

failurePropagationDefined

Failure declares no required propagation target

HIGH

failureEvaluation

Failure lacks a sufficient or residual evaluation

HIGH

failureArgument

Failure records a positive evaluation without an argument

HIGH

failureSeverityValue

Failure has an invalid severity value

HIGH

interfacePointS10Failure

Interface-point analysis contains no required S10 failure

HIGH

interfacePointAnalysisCoverage

Analysis omits an interface point

HIGH

failureNameSeverityMatch

Failure name contradicts its severity

MODERATE

failureDescriptionElement

Failure description omits its element name at the start

MODERATE

failureDescriptionInterface

Failure description omits its interface name after the element name

MODERATE

failureQmSeverity

QM failure reaches S10 severity

HIGH

failureS10SafetyMeasures

Failure lacks a safety measure or valid independent failure

HIGH

failureTopLevelNoPropagation

Top-level failure declares propagation targets

MODERATE

forbiddenWordsInAnalysis

Analysis entity contains forbidden wording

MODERATE

interfacePointAnalysisUsedInNotEmpty

Interface-point analysis declares no required parent dependency

HIGH

interfacePointAnalysisTopLevelNoUsedIn

Top-level interface-point analysis declares parent dependencies

MODERATE

interfacePointAnalysisUsedInParentElement

Interface-point analysis links outside its eligible analysis parent

HIGH

interfacePointAsilUsedIn

Interface-point analysis has no parent dependency with sufficient ASIL

HIGH INFO

failureAsilBound

Failure exceeds its interface point's ASIL

HIGH INFO

failureAsilPropagation

Failure exceeds every propagation target's ASIL

HIGH INFO

failurePropagationUsedInConsistency

Failure propagates outside its declared interface dependencies

HIGH

failureSeverityPropagation

Failure exceeds every propagation target's severity

HIGH INFO

failureMultiplicityPropagation

Single-point failure propagates to a failure with incompatible multiplicity

HIGH

failureMultiplePointIndependent

Multiple-point failure cites no independent failure

HIGH

failureIndependentReference

Failure cites an invalid independent failure

HIGH MODERATE

failureChildPropagationCoverage

Failure lacks a contributing child failure

HIGH

interfacePointAnalysisChildContributionCoverage

Interface-point analysis lacks a contributing child analysis

HIGH

failurePropagationToBottomLevel

Failure propagates to a bottom-level failure

MODERATE

interfacePointAnalysisContributionToBottomLevel

Interface-point analysis contributes to a bottom-level interface

MODERATE

failurePropagationParentElement

Failure propagates outside its eligible analysis parent

HIGH

interfacePointAnalysisSubject

Interface-point analysis references another element's interface

HIGH

testCaseMustLiveInTestCaseContainer

Test case lacks a containing test specification

HIGH

nonTestsEntityInTestsPackage

Entity uses the wrong viewpoint package (Tests)

HIGH

testsClassesTopLevel

Tests class is nested inside another declaration

MODERATE

testsClassInstance

Tests class has no instance property in its file

MODERATE

testsClassPascalCase

Tests class name violates PascalCase

MODERATE

testsObjectCamelCase

Tests instance name violates camelCase

MODERATE

nameDefinedInTestsPackage

Tests entity has no required name

HIGH

descriptionDefinedInTestsPackage

Tests entity has no required description

HIGH

testCaseAsilDefined

Test case has no ASIL

HIGH

testCaseContainerElementDefined

Test specification has no subject element

HIGH

testCaseElementUnderTest

Test case identifies no element under test

HIGH

testCaseInterfacesUnderTest

Test case identifies no interface under test

HIGH

testCaseGivenWhenThen

Test case omits the required Given–When–Then sequence

MODERATE

forbiddenWordsInTests

Tests entity contains forbidden wording

MODERATE

testCaseVerifiesRequirement

Test case identifies no requirement to verify

HIGH

testCaseTraceability

Test case has no trace to an element, interface, or requirement

HIGH

testCaseAllocationConsistency

Test case exercises none of its verified requirements' allocated elements

HIGH

Context

nonContextEntityInContextPackage

Field

Description

Name

Entity uses the wrong viewpoint package (Context)

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH

Contract and evidence

A file under a .context package may only declare context-viewpoint entities (Element subclasses, InterfacePoint subclasses, DataType, DataElement, Parameter, Connector).

Corrective action

Move the declaration out of .context into the viewpoint package appropriate for its entity type.

Dispatch input

MetamodelEntity; once per viewpoint: true.

Kotlin declaration

com.stigway.metamodels.create.NonContextEntityInContextPackageRule

Kotlin implementation

com.stigway.metamodels.create.NonContextEntityInContextPackageRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/ViewpointPackageRules.kt:

override fun check(container: MetamodelEntity): List<ModelProblem> = buildFindingsForViewpoint(this, Viewpoint.CONTEXT, "context")

contextClassesTopLevel

Field

Description

Name

Context class is nested inside another declaration

Contributor unknown

false

Default severity

MODERATE

Possible finding severities

MODERATE

Contract and evidence

Every class declared in this viewpoint shall be directly in its Kotlin file, outside other classes, objects and functions.

Corrective action

Move the class to file scope in the same Kotlin file. Update type references and pass any required enclosing state explicitly; retain the model's object containment.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.ContextClassesTopLevelRule

Kotlin implementation

com.stigway.metamodels.create.ContextClassesTopLevelRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/ViewpointDeclarationRules.kt:

class ContextClassesTopLevelRule : ViewpointClassesTopLevelRule(Viewpoint.CONTEXT) { override val name = "Context class is nested inside another declaration" }

com.stigway.metamodels.create.ViewpointClassesTopLevelRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/ViewpointDeclarationRules.kt:

override fun check(index: ModelIndex): List<ModelProblem> = index.sourceFindings(this) { _, declaration -> if (declaration.kind == KotlinDeclarationKind.CLASS && !declaration.topLevel) "Class [${declaration.qualifiedName}] is nested; it shall be declared at file scope." else null }

contextClassInstance

Field

Description

Name

Context class has no instance property in its file

Contributor unknown

false

Default severity

MODERATE

Possible finding severities

MODERATE

Contract and evidence

Every concrete class in this viewpoint shall have at least one instance property in the same Kotlin file, either at file scope or as a member of a class or object. Multiple instances are allowed. Function-local variables do not satisfy this obligation. Abstract, sealed, enum, annotation and expect classes and interfaces are exempt.

Corrective action

Declare an instance property in the same Kotlin file (for example, val abc = ABC()), either at file scope or as a field of its owning model class or object. Keep member instances in their owning container; multiple instances of the same class are allowed.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.ContextClassInstanceRule

Kotlin implementation

com.stigway.metamodels.create.ContextClassInstanceRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/ViewpointDeclarationRules.kt:

class ContextClassInstanceRule : ViewpointClassInstanceRule(Viewpoint.CONTEXT) { override val name = "Context class has no instance property in its file" }

com.stigway.metamodels.create.ViewpointClassInstanceRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/ViewpointDeclarationRules.kt:

override fun check(index: ModelIndex): List<ModelProblem> { val counts = index.sourceFiles.filter { it.viewpoint == viewpoint }.associateWith { source -> val classes = source.declarations.filter { it.kind == KotlinDeclarationKind.CLASS } .mapTo(hashSetOf()) { it.qualifiedName } source.declarations.filter { it.kind == KotlinDeclarationKind.PROPERTY && (it.topLevel || it.memberProperty) } .mapNotNull { property -> val constructed = property.constructedType?.let { source.typeName(it, property) } constructed?.takeIf { it in classes } ?: property.declaredType?.let { source.typeName(it, property) } }.groupingBy { it }.eachCount() } return index.sourceFindings(this) { source, declaration -> if (!declaration.concrete) return@sourceFindings null val instances = counts.getValue(source)[declaration.qualifiedName] ?: 0 if (instances > 0) null else "Class [${declaration.qualifiedName}] has no instance property in this file; declare one at file scope or as a member of its owning class or object." } }

contextClassPascalCase

Field

Description

Name

Context class name violates PascalCase

Contributor unknown

false

Default severity

MODERATE

Possible finding severities

MODERATE

Contract and evidence

Class identifiers in this viewpoint shall start with an uppercase letter and contain only letters and digits (PascalCase).

Corrective action

Rename the class to PascalCase with the IDE's Rename refactoring, removing underscores and dashes, and update every type and constructor reference.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.ContextClassPascalCaseRule

Kotlin implementation

com.stigway.metamodels.create.ContextClassPascalCaseRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/ViewpointDeclarationRules.kt:

class ContextClassPascalCaseRule : ViewpointClassPascalCaseRule(Viewpoint.CONTEXT) { override val name = "Context class name violates PascalCase" }

com.stigway.metamodels.create.ViewpointClassPascalCaseRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/ViewpointDeclarationRules.kt:

override fun check(index: ModelIndex): List<ModelProblem> = index.sourceFindings(this) { _, declaration -> if (declaration.kind == KotlinDeclarationKind.CLASS && !ModelDeclarationNames.pascalCase(declaration.name)) "Class [${declaration.qualifiedName}] is not PascalCase." else null }

contextObjectCamelCase

Field

Description

Name

Context instance name violates camelCase

Contributor unknown

false

Default severity

MODERATE

Possible finding severities

MODERATE

Contract and evidence

Instance property and named object identifiers in this viewpoint shall start with a lowercase letter and contain only letters and digits (camelCase). Context declarations of ProvidedMethod and RequiredMethod, including derived types, retain the external API identifier.

Corrective action

Rename the property or named object to camelCase with the IDE's Rename refactoring, removing underscores and dashes. Update references and any configured or persisted model IDs affected by the rename.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.ContextObjectCamelCaseRule

Kotlin implementation

com.stigway.metamodels.create.ContextObjectCamelCaseRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/ViewpointDeclarationRules.kt:

class ContextObjectCamelCaseRule : ViewpointObjectCamelCaseRule(Viewpoint.CONTEXT) { override val name = "Context instance name violates camelCase" }

com.stigway.metamodels.create.ViewpointObjectCamelCaseRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/ViewpointDeclarationRules.kt:

override fun check(index: ModelIndex): List<ModelProblem> { val externalMethods = if (viewpoint == Viewpoint.CONTEXT) index.directMethodDeclarations() else emptySet() return index.sourceFindings(this) { _, declaration -> if (declaration.kind in setOf(KotlinDeclarationKind.PROPERTY, KotlinDeclarationKind.OBJECT) && declaration.qualifiedName !in externalMethods && !ModelDeclarationNames.camelCase(declaration.name) ) "Object [${declaration.qualifiedName}] is not camelCase." else null } }

nameDefinedInContextPackage

Field

Description

Name

Context entity has no required name

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH

Contract and evidence

Every context entity shall have a non-blank name.

Corrective action

Give the context entity a short domain name in its name.

Dispatch input

MetamodelEntity; once per viewpoint: true.

Kotlin declaration

com.stigway.metamodels.create.NameDefinedInContextPackageRule

Kotlin implementation

com.stigway.metamodels.create.NameDefinedInContextPackageRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/MetamodelPresenceRules.kt:

override fun check(container: MetamodelEntity): List<ModelProblem> = missingNameFindings(this, Viewpoint.CONTEXT)

descriptionDefinedInContextPackage

Field

Description

Name

Context entity has no required description

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH

Contract and evidence

Every context entity shall have a non-blank description.

Corrective action

Describe the context entity's purpose, boundary, or interface meaning in its description.

Dispatch input

MetamodelEntity; once per viewpoint: true.

Kotlin declaration

com.stigway.metamodels.create.DescriptionDefinedInContextPackageRule

Kotlin implementation

com.stigway.metamodels.create.DescriptionDefinedInContextPackageRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/MetamodelPresenceRules.kt:

override fun check(container: MetamodelEntity): List<ModelProblem> = missingDescriptionFindings(this, Viewpoint.CONTEXT)

elementAsilDefined

Field

Description

Name

Element has no ASIL

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH

Contract and evidence

Every Element shall define its required asil attribute.

Corrective action

Set the asil of Element using the applicable engineering evidence.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.context.ElementAsilDefinedRule

Kotlin implementation

com.stigway.metamodels.create.context.ElementAsilDefinedRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/context/ContextRules.kt:

class ElementAsilDefinedRule : RequiredAttributeRule<Element>( Element::class, Viewpoint.CONTEXT, "asil", FixValueKind.ASIL, missing = { it.asil == null }, ) { override val name = "Element has no ASIL" }

com.stigway.metamodels.create.RequiredAttributeRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/RequiredAttributeRule.kt:

override fun check(index: ModelIndex): List<ModelProblem> = index.subjectEntities .filter { type.java.isInstance(it) && missing(type.java.cast(it)) } .map { entity -> ModelProblem( rule = this, severity = defaultSeverity, entityName = entity.id, ownerElementId = index.ownerElement(entity)?.id, message = "${entity.idLabel} has no required $attribute value.", remediation = "Set $attribute on ${entity.idLabel} from the model's engineering evidence.", quickFixes = if (valueKind == FixValueKind.MULTIPLICITY) { Multiplicity.entries.map { SetArgumentFix( entity.id, attribute, FixExpression("Multiplicity.${it.name}") ) } } else listOf(PromptSetArgumentFix(entity.id, attribute, valueKind, listArgument = listArgument)), ) }

forbiddenWordsInContext

Field

Description

Name

Context entity contains forbidden wording

Contributor unknown

false

Default severity

MODERATE

Possible finding severities

MODERATE

Contract and evidence

String attributes in the context viewpoint shall not contain the configured forbidden words. The default list only rejects explicit unfinished-work markers: tbd, tbc, todo, fixme. Narrative failure descriptions and assessment arguments may use uncertainty and qualitative wording. Check constructor attributes, including names, descriptions, arguments, comments, verification criteria, collections, and nested metadata. Match whole words/phrases without regard to case. Referenced model entities are checked in their own viewpoint and module scope. KDoc, source comments, generated identities, and enum names are not string attributes.

Corrective action

Replace the reported wording in the named attribute with precise, testable conditions and justified values. Obtain missing engineering decisions before completing the statement.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.ForbiddenWordsInContextRule

Kotlin implementation

com.stigway.metamodels.create.ForbiddenWordsInContextRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/ForbiddenWordsRules.kt:

class ForbiddenWordsInContextRule : ForbiddenWordsInViewpointRule(Viewpoint.CONTEXT) { override val name = "Context entity contains forbidden wording" }

com.stigway.metamodels.create.ForbiddenWordsInViewpointRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/ForbiddenWordsRules.kt:

final override fun check(index: ModelIndex): List<ModelProblem> = buildList { for (entity in index.subjectEntities.filter { index.viewpoint(it) == viewpoint }.sortedBy { it.id }) { for ((attribute, text) in modelStringAttributes(entity)) { val found = findForbiddenPhrases(text, phrases) if (found.isEmpty()) continue add( ModelProblem( rule = this@ForbiddenWordsInViewpointRule, severity = defaultSeverity, entityName = entity.id, subjectId = "${entity.id}:$attribute", message = "${entity.idLabel} contains forbidden words in `$attribute`: ${found.joinToString(", ")}.", remediation = "Replace the reported wording in `$attribute` on ${entity.idLabel} with precise, testable " + "conditions: ${found.joinToString(", ")}. Resolve missing engineering decisions " + "before using this text as released evidence.", quickFixes = if ('.' !in attribute && '[' !in attribute) { listOf(RewriteStringArgumentFix(entity.id, attribute, text)) } else emptyList(), ) ) } } }

elementAllocatedAsilBound

Field

Description

Name

Element allocates an ASIL above its own ASIL

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH INFO

Contract and evidence

An element's allocatedAsil, when declared, shall not exceed its asil (HIGH). A lower allocatedAsil produces INFO on the element.

Corrective action

Review the allocated requirements and the element's development classification. Correct allocatedAsil or asil using that evidence.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.context.ElementAllocatedAsilBoundRule

Kotlin implementation

com.stigway.metamodels.create.context.ElementAllocatedAsilBoundRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/context/ContextRules.kt:

override fun check(index: ModelIndex): List<ModelProblem> = index.subjectElements.mapNotNull { element -> val allocatedAsil = element.allocatedAsil ?: return@mapNotNull null val elementAsil = element.asil ?: return@mapNotNull null if (allocatedAsil <= elementAsil) return@mapNotNull classificationDifference( this, index, ClassificationValue(element as MetamodelEntity, elementAsil), listOf(ClassificationValue(element, allocatedAsil)), "ASIL", "declared allocatedAsil", ) { listOf(element) } ModelProblem( rule = this, severity = defaultSeverity, entityName = element.id, ownerElementId = element.id, message = "${element.idLabel} has allocatedAsil ${allocatedAsil.name}, which exceeds its ASIL ${elementAsil.name}.", quickFixes = listOf( PromptSetArgumentFix(element.id, "allocatedAsil", FixValueKind.ASIL), PromptSetArgumentFix(element.id, "asil", FixValueKind.ASIL), ), ) }

interfacePointAsilBound

Field

Description

Name

Provided interface point exceeds its element's ASIL limit

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH INFO

Contract and evidence

An interface point's effectiveAsil, when provided by an element, shall not exceed allocatedAsil when declared, otherwise asil. Provided ports, published data and provided functions are checked; required ports, subscribed data and called methods may have any ASIL. A shared definition is checked at the local provided port or member use. A complete nonempty set of provided interface points below the selected bound produces INFO on the element.

Corrective action

Review the interface point classifications and their element's requirement allocation.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.context.InterfacePointAsilBoundRule

Kotlin implementation

com.stigway.metamodels.create.context.InterfacePointAsilBoundRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/context/InterfacePointAsilBoundRule.kt:

override fun check(index: ModelIndex): List<ModelProblem> = buildList { for (element in index.elements) { val elementEntity = element as MetamodelEntity val limit = element.allocatedAsil ?: element.asil ?: continue val attribute = if (element.allocatedAsil != null) "allocatedAsil" else "asil" val members = index.providedInterfacePoints(element) for ((point, target) in members) { val value = point.effectiveAsil ?: continue if ((!index.isSubject(target) && !index.isSubject(elementEntity)) || value <= limit) continue add( ModelProblem( this@InterfacePointAsilBoundRule, defaultSeverity, "${target.idLabel} provides ${point.idLabel} at ASIL ${value.name}, " + "above ${element.idLabel} $attribute ${limit.name}.", entityName = target.id, ownerElementId = element.id, subjectId = "${target.id}#providedAsil:${point.id}:$attribute", relatedEntityIds = listOf(element.id, point.id).distinct().filter { it != target.id }, ) ) } classificationDifference( this@InterfacePointAsilBoundRule, index, ClassificationValue(elementEntity, limit), members.map { ClassificationValue(it.point as MetamodelEntity, it.point.effectiveAsil) }, attribute, "provided interface points", ) { listOf(element) }?.let(::add) } }

interfacePointParentAsilBound

Field

Description

Name

Interface point exceeds its enclosing interface point's ASIL

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH

Contract and evidence

An interface point's effectiveAsil shall not exceed its nearest enclosing interface point's effectiveAsil. This applies to both provided and required interface points, including member uses enclosed by their local port. A shared definition retains its declaration parent. If either classification is unresolved or there is no enclosing interface point, this check does not apply. The element's provision limit is checked separately.

Corrective action

Review the child and enclosing interface classifications so the child does not exceed its parent.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.context.InterfacePointParentAsilBoundRule

Kotlin implementation

com.stigway.metamodels.create.context.InterfacePointParentAsilBoundRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/context/InterfacePointParentAsilBoundRule.kt:

override fun check(index: ModelIndex): List<ModelProblem> = buildList { for (point in index.subjectEntities.filterIsInstance<InterfacePoint>()) { val parent = index.enclosingInterfacePoint(point) ?: continue val value = point.effectiveAsil ?: continue val limit = parent.effectiveAsil ?: continue if (value <= limit) continue val entity = point as MetamodelEntity add( ModelProblem( this@InterfacePointParentAsilBoundRule, defaultSeverity, "${point.idLabel} has effective ASIL ${value.name}, above enclosing interface point " + "${parent.idLabel} effective ASIL ${limit.name}.", entityName = entity.id, ownerElementId = index.ownerElement(entity)?.id, subjectId = "${entity.id}#parentAsil:${parent.id}", relatedEntityIds = listOf(parent.id), ) ) } }

elementParentDefined

Field

Description

Name

Element has no required parent

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH

Contract and evidence

An element with isTopLevel=false shall reference its parent element.

Corrective action

Set the parent of Element using the applicable engineering evidence.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.context.ElementParentDefinedRule

Kotlin implementation

com.stigway.metamodels.create.context.ElementParentDefinedRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/context/ContextRules.kt:

class ElementParentDefinedRule : RequiredAttributeRule<Element>( Element::class, Viewpoint.CONTEXT, "parent", FixValueKind.ELEMENT_REFERENCE, missing = { !it.isTopLevel && it.parent == null }, ) { override val name = "Element has no required parent" override val description = "An element with isTopLevel=false shall reference its parent element." }

com.stigway.metamodels.create.RequiredAttributeRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/RequiredAttributeRule.kt:

override fun check(index: ModelIndex): List<ModelProblem> = index.subjectEntities .filter { type.java.isInstance(it) && missing(type.java.cast(it)) } .map { entity -> ModelProblem( rule = this, severity = defaultSeverity, entityName = entity.id, ownerElementId = index.ownerElement(entity)?.id, message = "${entity.idLabel} has no required $attribute value.", remediation = "Set $attribute on ${entity.idLabel} from the model's engineering evidence.", quickFixes = if (valueKind == FixValueKind.MULTIPLICITY) { Multiplicity.entries.map { SetArgumentFix( entity.id, attribute, FixExpression("Multiplicity.${it.name}") ) } } else listOf(PromptSetArgumentFix(entity.id, attribute, valueKind, listArgument = listArgument)), ) }

elementTopLevelNoParent

Field

Description

Name

Top-level element declares a parent

Contributor unknown

false

Default severity

MODERATE

Possible finding severities

MODERATE

Contract and evidence

An element with isTopLevel=true shall have no parent.

Corrective action

Check the element's isTopLevel flag against the agreed model scope. If the flag is correct, remove the references in parent; otherwise correct the flag to match the intended hierarchy.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.ElementTopLevelNoParentRule

Kotlin implementation

com.stigway.metamodels.create.ElementTopLevelNoParentRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/BoundaryRules.kt:

class ElementTopLevelNoParentRule : BoundaryLinksRule<Element>( Element::class, Viewpoint.CONTEXT, "parent", "isTopLevel", { it.isTopLevel && it.parent != null }, ) { override val name = "Top-level element declares a parent" override val description = "An element with isTopLevel=true shall have no parent." }

com.stigway.metamodels.create.BoundaryLinksRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/BoundaryRules.kt:

override fun check(index: ModelIndex): List<ModelProblem> = index.subjectEntities .filter { type.java.isInstance(it) && violates(type.java.cast(it)) } .map { entity -> ModelProblem( this, defaultSeverity, "${entity.idLabel} has $attribute references although its element has $boundary=true.", entityName = entity.id, ownerElementId = index.ownerElement(entity)?.id, remediation = "Review the element's $boundary declaration and the authored $attribute references." ) }

elementInParentDesign

Field

Description

Name

Element names a parent whose design omits it

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH

Contract and evidence

An element with a parent shall be listed in that parent's Design.children.

Corrective action

Add the element to its parent's Design.children. If it belongs to a different parent, correct parent and the corresponding design decomposition together.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.context.ElementInParentDesignRule

Kotlin implementation

com.stigway.metamodels.create.context.ElementInParentDesignRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/context/ContextRules.kt:

override fun check(index: ModelIndex): List<ModelProblem> = index.subjectElements.mapNotNull { element -> val parent = element.parent ?: return@mapNotNull null index.requireCompleteContent(listOf(parent)) if (element in index.designChildrenOf(parent)) return@mapNotNull null ModelProblem( this, defaultSeverity, "${element.idLabel} is not listed in Design.children of its parent ${parent.idLabel}.", entityName = element.id, ownerElementId = element.id, relatedEntityIds = listOf(parent.id), remediation = "Review the element's parent and the parent's declared Design.children.", ) }

interfaceEntityAsilDefined

Field

Description

Name

Context entity has no required ASIL

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH

Contract and evidence

Every interface point shall resolve an effectiveAsil from its own declaration, referenced definition, enclosing interface points or owning element. Connectors and other ASIL-bearing context entities shall define their ASIL.

Corrective action

Set asil on the interface point, connector, or other context entity to its justified safety classification.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.InterfaceEntityAsilDefinedRule

Kotlin implementation

com.stigway.metamodels.create.InterfaceEntityAsilDefinedRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/RequiredAttributeRule.kt:

override fun check(index: ModelIndex): List<ModelProblem> = index.subjectEntities.filter { index.viewpoint(it) == Viewpoint.CONTEXT && when (it) { is Element, is Context, is Requirements, is Design, is Analysis, is InterfacePointAnalysis, is Tests, is RequirementNote -> false is InterfacePoint -> it.effectiveAsil == null else -> it.asil == null } }.map { ModelProblem( this, defaultSeverity, "${it.idLabel} has no ASIL classification.", entityName = it.id, ownerElementId = index.ownerElement(it)?.id, quickFixes = listOf(PromptSetArgumentFix(it.id, "asil", FixValueKind.ASIL)) ) }

portMemberUse

Field

Description

Name

Port member use references a member outside its service interface

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH

Contract and evidence

A port-member use shall reference a member declared by the port's service interface.

Corrective action

Select a member from the service interface referenced by port, or correct the port's interface reference.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.context.PortMemberUseRule

Kotlin implementation

com.stigway.metamodels.create.context.PortMemberUseRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/context/PortMemberUseRule.kt:

override fun check(index: ModelIndex): List<ModelProblem> = index.subjectEntities.filterIsInstance<PortMemberUse<*>>() .filterNot(index::memberBelongsToInterface) .map { use -> ModelProblem( rule = this, severity = defaultSeverity, entityName = use.id, message = "${use.idLabel} selects ${use.member.idLabel}, which does not belong to the " + "service interface of ${use.port.idLabel}." ) }

portMemberUseAsilBound

Field

Description

Name

Port member use exceeds its referenced member's ASIL

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH

Contract and evidence

A port-member use's effectiveAsil shall not exceed its referenced member's effectiveAsil, including classification inherited by that member from its enclosing declarations. This applies to both provided and required uses. If either classification is unresolved, this comparison does not apply. The enclosing port and provided-interface element limits are checked separately.

Corrective action

Use the member's inherited classification, or review the interface definition so a local use does not exceed it.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.context.PortMemberUseAsilBoundRule

Kotlin implementation

com.stigway.metamodels.create.context.PortMemberUseAsilBoundRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/context/PortMemberUseAsilBoundRule.kt:

override fun check(index: ModelIndex): List<ModelProblem> = buildList { for (use in index.subjectEntities.filterIsInstance<PortMemberUse<*>>()) { val value = use.effectiveAsil ?: continue val limit = use.member.effectiveAsil ?: continue if (value <= limit) continue add( ModelProblem( this@PortMemberUseAsilBoundRule, defaultSeverity, "${use.idLabel} has effective ASIL ${value.name}, above referenced member " + "${use.member.idLabel} effective ASIL ${limit.name}.", entityName = use.id, ownerElementId = index.ownerElement(use)?.id, subjectId = "${use.id}#memberAsil:${use.member.id}", relatedEntityIds = listOf(use.member.id), ) ) } }

requiredMethodDefinitionAsilBound

Field

Description

Name

Required method exceeds its definition's ASIL

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH

Contract and evidence

A required method's effectiveAsil shall not exceed its referenced definition's effectiveAsil. Classification inherited by the definition is included. If the definition or either classification is absent, this comparison does not apply.

Corrective action

Use the definition's inherited classification, or review the referenced contract so the required method does not exceed it.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.context.RequiredMethodDefinitionAsilBoundRule

Kotlin implementation

com.stigway.metamodels.create.context.RequiredMethodDefinitionAsilBoundRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/context/RequiredMethodDefinitionAsilBoundRule.kt:

override fun check(index: ModelIndex): List<ModelProblem> = buildList { for (method in index.subjectEntities.filterIsInstance<RequiredMethod>()) { val definition = method.definition ?: continue val value = method.effectiveAsil ?: continue val limit = definition.effectiveAsil ?: continue if (value <= limit) continue add( ModelProblem( this@RequiredMethodDefinitionAsilBoundRule, defaultSeverity, "${method.idLabel} has effective ASIL ${value.name}, above referenced definition " + "${definition.idLabel} effective ASIL ${limit.name}.", entityName = method.id, ownerElementId = index.ownerElement(method)?.id, subjectId = "${method.id}#definitionAsil:${definition.id}", relatedEntityIds = listOf(definition.id), ) ) } }

unresolvedInterfaceMember

Field

Description

Name

Service member has no resolved interface definition

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH

Contract and evidence

A service member shall have a resolved interface definition. Findings belong to the module declaring the member.

Corrective action

Resolve the reported service-member reference to a declared interface member. Correct the source reference or supply the missing interface definition, then refresh the imported model.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.context.UnresolvedInterfaceMemberRule

Kotlin implementation

com.stigway.metamodels.create.context.UnresolvedInterfaceMemberRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/context/UnresolvedInterfaceMemberRule.kt:

override fun check(index: ModelIndex): List<ModelProblem> { return index.subjectEntities.filterIsInstance<UnresolvedInterfaceMember>().map(::problem) }

Requirements

requirementMustLiveInRequirementContainer

Field

Description

Name

Requirement lacks a containing requirements specification

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH

Contract and evidence

Every Requirement shall be declared as a property of a Requirements subclass; top-level val xxx = Requirement(...) declarations are not allowed.

Corrective action

Move the requirement into the appropriate Requirements subclass as a named val property, preserving its attributes and traceability links.

Dispatch input

MetamodelEntity; once per viewpoint: true.

Kotlin declaration

com.stigway.metamodels.create.requirements.RequirementMustLiveInRequirementContainerRule

Kotlin implementation

com.stigway.metamodels.create.requirements.RequirementMustLiveInRequirementContainerRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/requirements/RequirementRules.kt:

override fun check(container: MetamodelEntity): List<ModelProblem> { return ModelIndex.current().subjectEntities .filterIsInstance<Requirement>() .filter { it.ownerContainer == null } .map { requirement -> val ref = requirement.idLabel val site = requirement.declaringClassName ?: "(unknown declaring class)" ModelProblem( rule = this, severity = defaultSeverity, entityName = requirement.id, message = "Requirement $ref is not declared inside any Requirements " + "(declared at: $site). Move it into a `Requirements` subclass " + "as a `val` property.", remediation = "Move requirement $ref into the appropriate Requirements as a " + "`val` property. Keep the requirement data unchanged unless the " + "free-floating declaration itself is the wrong requirement.", quickFixes = listOf( MoveDeclarationFix(requirement.id, MoveTargetKind.REQUIREMENT_CONTAINER), ), ) } }

nonRequirementsEntityInRequirementsPackage

Field

Description

Name

Entity uses the wrong viewpoint package (Requirements)

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH

Contract and evidence

A file under a .requirements package may only declare requirements-viewpoint entities (Requirement, Requirements, RequirementNote).

Corrective action

Move the declaration out of .requirements into the viewpoint package appropriate for its entity type.

Dispatch input

MetamodelEntity; once per viewpoint: true.

Kotlin declaration

com.stigway.metamodels.create.NonRequirementsEntityInRequirementsPackageRule

Kotlin implementation

com.stigway.metamodels.create.NonRequirementsEntityInRequirementsPackageRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/ViewpointPackageRules.kt:

override fun check(container: MetamodelEntity): List<ModelProblem> = buildFindingsForViewpoint(this, Viewpoint.REQUIREMENTS, "requirements")

requirementsClassesTopLevel

Field

Description

Name

Requirements class is nested inside another declaration

Contributor unknown

false

Default severity

MODERATE

Possible finding severities

MODERATE

Contract and evidence

Every class declared in this viewpoint shall be directly in its Kotlin file, outside other classes, objects and functions.

Corrective action

Move the class to file scope in the same Kotlin file. Update type references and pass any required enclosing state explicitly; retain the model's object containment.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.RequirementsClassesTopLevelRule

Kotlin implementation

com.stigway.metamodels.create.RequirementsClassesTopLevelRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/ViewpointDeclarationRules.kt:

class RequirementsClassesTopLevelRule : ViewpointClassesTopLevelRule(Viewpoint.REQUIREMENTS) { override val name = "Requirements class is nested inside another declaration" }

com.stigway.metamodels.create.ViewpointClassesTopLevelRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/ViewpointDeclarationRules.kt:

override fun check(index: ModelIndex): List<ModelProblem> = index.sourceFindings(this) { _, declaration -> if (declaration.kind == KotlinDeclarationKind.CLASS && !declaration.topLevel) "Class [${declaration.qualifiedName}] is nested; it shall be declared at file scope." else null }

requirementsClassInstance

Field

Description

Name

Requirements class has no instance property in its file

Contributor unknown

false

Default severity

MODERATE

Possible finding severities

MODERATE

Contract and evidence

Every concrete class in this viewpoint shall have at least one instance property in the same Kotlin file, either at file scope or as a member of a class or object. Multiple instances are allowed. Function-local variables do not satisfy this obligation. Abstract, sealed, enum, annotation and expect classes and interfaces are exempt.

Corrective action

Declare an instance property in the same Kotlin file (for example, val abc = ABC()), either at file scope or as a field of its owning model class or object. Keep member instances in their owning container; multiple instances of the same class are allowed.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.RequirementsClassInstanceRule

Kotlin implementation

com.stigway.metamodels.create.RequirementsClassInstanceRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/ViewpointDeclarationRules.kt:

class RequirementsClassInstanceRule : ViewpointClassInstanceRule(Viewpoint.REQUIREMENTS) { override val name = "Requirements class has no instance property in its file" }

com.stigway.metamodels.create.ViewpointClassInstanceRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/ViewpointDeclarationRules.kt:

override fun check(index: ModelIndex): List<ModelProblem> { val counts = index.sourceFiles.filter { it.viewpoint == viewpoint }.associateWith { source -> val classes = source.declarations.filter { it.kind == KotlinDeclarationKind.CLASS } .mapTo(hashSetOf()) { it.qualifiedName } source.declarations.filter { it.kind == KotlinDeclarationKind.PROPERTY && (it.topLevel || it.memberProperty) } .mapNotNull { property -> val constructed = property.constructedType?.let { source.typeName(it, property) } constructed?.takeIf { it in classes } ?: property.declaredType?.let { source.typeName(it, property) } }.groupingBy { it }.eachCount() } return index.sourceFindings(this) { source, declaration -> if (!declaration.concrete) return@sourceFindings null val instances = counts.getValue(source)[declaration.qualifiedName] ?: 0 if (instances > 0) null else "Class [${declaration.qualifiedName}] has no instance property in this file; declare one at file scope or as a member of its owning class or object." } }

requirementsClassPascalCase

Field

Description

Name

Requirements class name violates PascalCase

Contributor unknown

false

Default severity

MODERATE

Possible finding severities

MODERATE

Contract and evidence

Class identifiers in this viewpoint shall start with an uppercase letter and contain only letters and digits (PascalCase).

Corrective action

Rename the class to PascalCase with the IDE's Rename refactoring, removing underscores and dashes, and update every type and constructor reference.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.RequirementsClassPascalCaseRule

Kotlin implementation

com.stigway.metamodels.create.RequirementsClassPascalCaseRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/ViewpointDeclarationRules.kt:

class RequirementsClassPascalCaseRule : ViewpointClassPascalCaseRule(Viewpoint.REQUIREMENTS) { override val name = "Requirements class name violates PascalCase" }

com.stigway.metamodels.create.ViewpointClassPascalCaseRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/ViewpointDeclarationRules.kt:

override fun check(index: ModelIndex): List<ModelProblem> = index.sourceFindings(this) { _, declaration -> if (declaration.kind == KotlinDeclarationKind.CLASS && !ModelDeclarationNames.pascalCase(declaration.name)) "Class [${declaration.qualifiedName}] is not PascalCase." else null }

requirementsObjectCamelCase

Field

Description

Name

Requirements instance name violates camelCase

Contributor unknown

false

Default severity

MODERATE

Possible finding severities

MODERATE

Contract and evidence

Instance property and named object identifiers in this viewpoint shall start with a lowercase letter and contain only letters and digits (camelCase). Context declarations of ProvidedMethod and RequiredMethod, including derived types, retain the external API identifier.

Corrective action

Rename the property or named object to camelCase with the IDE's Rename refactoring, removing underscores and dashes. Update references and any configured or persisted model IDs affected by the rename.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.RequirementsObjectCamelCaseRule

Kotlin implementation

com.stigway.metamodels.create.RequirementsObjectCamelCaseRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/ViewpointDeclarationRules.kt:

class RequirementsObjectCamelCaseRule : ViewpointObjectCamelCaseRule(Viewpoint.REQUIREMENTS) { override val name = "Requirements instance name violates camelCase" }

com.stigway.metamodels.create.ViewpointObjectCamelCaseRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/ViewpointDeclarationRules.kt:

override fun check(index: ModelIndex): List<ModelProblem> { val externalMethods = if (viewpoint == Viewpoint.CONTEXT) index.directMethodDeclarations() else emptySet() return index.sourceFindings(this) { _, declaration -> if (declaration.kind in setOf(KotlinDeclarationKind.PROPERTY, KotlinDeclarationKind.OBJECT) && declaration.qualifiedName !in externalMethods && !ModelDeclarationNames.camelCase(declaration.name) ) "Object [${declaration.qualifiedName}] is not camelCase." else null } }

nameDefinedInRequirementsPackage

Field

Description

Name

Requirements entity has no required name

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH

Contract and evidence

Every requirements entity shall have a non-blank name.

Corrective action

Give the requirement or requirements container a short name in its name.

Dispatch input

MetamodelEntity; once per viewpoint: true.

Kotlin declaration

com.stigway.metamodels.create.NameDefinedInRequirementsPackageRule

Kotlin implementation

com.stigway.metamodels.create.NameDefinedInRequirementsPackageRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/MetamodelPresenceRules.kt:

override fun check(container: MetamodelEntity): List<ModelProblem> = missingNameFindings(this, Viewpoint.REQUIREMENTS)

descriptionDefinedInRequirementsPackage

Field

Description

Name

Requirements entity has no required description

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH

Contract and evidence

Every requirements entity shall have a non-blank description.

Corrective action

Write the required behavior in the requirement's description, or describe the scope of the requirements container.

Dispatch input

MetamodelEntity; once per viewpoint: true.

Kotlin declaration

com.stigway.metamodels.create.DescriptionDefinedInRequirementsPackageRule

Kotlin implementation

com.stigway.metamodels.create.DescriptionDefinedInRequirementsPackageRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/MetamodelPresenceRules.kt:

override fun check(container: MetamodelEntity): List<ModelProblem> = missingDescriptionFindings(this, Viewpoint.REQUIREMENTS)

requirementAsilDefined

Field

Description

Name

Requirement has no ASIL

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH

Contract and evidence

Every Requirement shall define its required asil attribute.

Corrective action

Set the asil of Requirement using the applicable engineering evidence.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.requirements.RequirementAsilDefinedRule

Kotlin implementation

com.stigway.metamodels.create.requirements.RequirementAsilDefinedRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/requirements/RequirementRules.kt:

class RequirementAsilDefinedRule : RequiredAttributeRule<Requirement>( Requirement::class, Viewpoint.REQUIREMENTS, "asil", FixValueKind.ASIL, missing = { it.asil == null }, ) { override val name = "Requirement has no ASIL" }

com.stigway.metamodels.create.RequiredAttributeRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/RequiredAttributeRule.kt:

override fun check(index: ModelIndex): List<ModelProblem> = index.subjectEntities .filter { type.java.isInstance(it) && missing(type.java.cast(it)) } .map { entity -> ModelProblem( rule = this, severity = defaultSeverity, entityName = entity.id, ownerElementId = index.ownerElement(entity)?.id, message = "${entity.idLabel} has no required $attribute value.", remediation = "Set $attribute on ${entity.idLabel} from the model's engineering evidence.", quickFixes = if (valueKind == FixValueKind.MULTIPLICITY) { Multiplicity.entries.map { SetArgumentFix( entity.id, attribute, FixExpression("Multiplicity.${it.name}") ) } } else listOf(PromptSetArgumentFix(entity.id, attribute, valueKind, listArgument = listArgument)), ) }

requirementVerificationCriteriaDefined

Field

Description

Name

Requirement has no verification criteria

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH

Contract and evidence

Every Requirement shall define its required verificationCriteria attribute.

Corrective action

Add measurable acceptance conditions in verificationCriteria, including the inputs, expected result, and any tolerances needed to decide whether the requirement is satisfied.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.RequirementVerificationCriteriaDefinedRule

Kotlin implementation

com.stigway.metamodels.create.RequirementVerificationCriteriaDefinedRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/RequiredAttributeRule.kt:

class RequirementVerificationCriteriaDefinedRule : RequiredAttributeRule<Requirement>( Requirement::class, Viewpoint.REQUIREMENTS, "verificationCriteria", FixValueKind.MULTILINE_STRING, missing = { it.verificationCriteria.isNullOrBlank() }, ) { override val name = "Requirement has no verification criteria" override val remediation = "Add measurable acceptance conditions in `verificationCriteria`, including the inputs, expected result, " + "and any tolerances needed to decide whether the requirement is satisfied." }

com.stigway.metamodels.create.RequiredAttributeRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/RequiredAttributeRule.kt:

override fun check(index: ModelIndex): List<ModelProblem> = index.subjectEntities .filter { type.java.isInstance(it) && missing(type.java.cast(it)) } .map { entity -> ModelProblem( rule = this, severity = defaultSeverity, entityName = entity.id, ownerElementId = index.ownerElement(entity)?.id, message = "${entity.idLabel} has no required $attribute value.", remediation = "Set $attribute on ${entity.idLabel} from the model's engineering evidence.", quickFixes = if (valueKind == FixValueKind.MULTIPLICITY) { Multiplicity.entries.map { SetArgumentFix( entity.id, attribute, FixExpression("Multiplicity.${it.name}") ) } } else listOf(PromptSetArgumentFix(entity.id, attribute, valueKind, listArgument = listArgument)), ) }

requirementContainerElementDefined

Field

Description

Name

Requirements specification has no subject element

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH

Contract and evidence

Every Requirements shall define its required element attribute.

Corrective action

Set the element of Requirements using the applicable engineering evidence.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.RequirementContainerElementDefinedRule

Kotlin implementation

com.stigway.metamodels.create.RequirementContainerElementDefinedRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/RequiredAttributeRule.kt:

class RequirementContainerElementDefinedRule : RequiredAttributeRule<Requirements>( Requirements::class, Viewpoint.REQUIREMENTS, "element", FixValueKind.ELEMENT_REFERENCE, missing = { ModelIndex.current().ownerElement(it) == null }, ) { override val name = "Requirements specification has no subject element" }

com.stigway.metamodels.create.RequiredAttributeRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/RequiredAttributeRule.kt:

override fun check(index: ModelIndex): List<ModelProblem> = index.subjectEntities .filter { type.java.isInstance(it) && missing(type.java.cast(it)) } .map { entity -> ModelProblem( rule = this, severity = defaultSeverity, entityName = entity.id, ownerElementId = index.ownerElement(entity)?.id, message = "${entity.idLabel} has no required $attribute value.", remediation = "Set $attribute on ${entity.idLabel} from the model's engineering evidence.", quickFixes = if (valueKind == FixValueKind.MULTIPLICITY) { Multiplicity.entries.map { SetArgumentFix( entity.id, attribute, FixExpression("Multiplicity.${it.name}") ) } } else listOf(PromptSetArgumentFix(entity.id, attribute, valueKind, listArgument = listArgument)), ) }

requirementContainerSubject

Field

Description

Name

Requirement names a different subject from its specification

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH

Contract and evidence

A requirement shall belong to a requirements specification for its subject element.

Corrective action

Place the requirement in the Requirements container for its subject element. If the subject reference is incorrect, fix the requirement's element.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.requirements.RequirementContainerSubjectRule

Kotlin implementation

com.stigway.metamodels.create.requirements.RequirementContainerSubjectRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/requirements/RequirementCoverageRules.kt:

override fun check(index: ModelIndex): List<ModelProblem> = index.subjectRequirements.mapNotNull { requirement -> val subject = requirement.ownerContainer?.let(index::ownerElement) ?: return@mapNotNull null if (subject === requirement.element) return@mapNotNull null ModelProblem( this, defaultSeverity, "${requirement.idLabel} belongs to a specification for a different element.", entityName = requirement.id, ownerElementId = subject.id ) }

requirementNormativeModal

Field

Description

Name

Requirement omits a recognized normative modal

Contributor unknown

false

Default severity

MODERATE

Possible finding severities

MODERATE

Contract and evidence

A requirement's description shall contain one recognized normative modal: shall (required), shall not (forbidden), should (recommended), should not (recommended not to), may (allowed).

Corrective action

Write the requirement's description with a recognized modal expressing the intended obligation, prohibition, recommendation, or permission. Preserve the subject, conditions, and required behavior.

Dispatch input

Requirements; once per viewpoint: false.

Kotlin declaration

com.stigway.metamodels.create.requirements.RequirementNormativeModalRule

Kotlin implementation

com.stigway.metamodels.create.requirements.RequirementNormativeModalRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/requirements/RequirementRules.kt:

override fun check(container: MetamodelEntity): List<ModelProblem> { val problems = mutableListOf<ModelProblem>() for ((_, req) in container.allRequirements()) { val text = req.description ?: continue if (!containsAcceptedRequirementModal(text)) { val rewrite = rewriteLegacyRequirementModal(text) val modalList = RequirementModal.entries.joinToString(", ") { "`${it.phrase}`" } problems += ModelProblem( rule = this, severity = defaultSeverity, entityName = req.id, message = "${req.idLabel} does not contain a recognized normative modal.", remediation = if (rewrite != null) { "Replace '${rewrite.sourcePhrase}' in requirement ${req.idLabel} with " + "'${rewrite.modal.phrase}' (${rewrite.modal.meaning}) while keeping " + "the rest of the description unchanged." } else { "Rewrite requirement ${req.idLabel} to use one recognized normative modal: " + "$modalList." }, quickFixes = rewrite?.let { listOf(RewriteStringArgumentFix(req.id, "description", it.rewrittenText)) }.orEmpty(), ) } } return problems }

subjectBeforeVerbInRequirement

Field

Description

Name

Requirement omits its subject before the normative modal

Contributor unknown

false

Default severity

MODERATE

Possible finding severities

MODERATE

Contract and evidence

A requirement's description shall mention the subject element's name before the first normative modal.

Corrective action

Name the subject element before the first normative modal in description. If the statement concerns a different element, correct the requirement's element reference.

Dispatch input

Requirements; once per viewpoint: false.

Kotlin declaration

com.stigway.metamodels.create.requirements.SubjectBeforeVerbInRequirementRule

Kotlin implementation

com.stigway.metamodels.create.requirements.SubjectBeforeVerbInRequirementRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/requirements/RequirementRules.kt:

override fun check(container: MetamodelEntity): List<ModelProblem> { val problems = mutableListOf<ModelProblem>() for ((_, req) in container.allRequirements()) { val text = req.description ?: continue val elementName = req.element.name if (elementName.isNullOrBlank()) continue val verbMatch = verbPattern.find(text) ?: continue val textBeforeVerb = text.substring(0, verbMatch.range.first) // Check if element name appears before the modal (case-sensitive match). if (!textBeforeVerb.contains(elementName)) { problems += ModelProblem( rule = this, severity = defaultSeverity, entityName = req.id, message = "${req.idLabel} does not mention the name '$elementName' of ${req.element.idLabel} before '${verbMatch.value}'.", remediation = "Rewrite the description of ${req.idLabel} so the subject element " + "'$elementName' appears before the normative modal '${verbMatch.value}'. " + "If the requirement is about a different element, fix this requirement's " + "`element` reference.", quickFixes = listOf( RewriteStringArgumentFix(req.id, "description", "$elementName ${text.trimStart()}"), PromptSetArgumentFix(req.id, "element", FixValueKind.ELEMENT_REFERENCE), ), ) } } return problems }

forbiddenWordsInRequirement

Field

Description

Name

Requirements entity contains forbidden wording

Contributor unknown

false

Default severity

MODERATE

Possible finding severities

MODERATE

Contract and evidence

String attributes in the requirements viewpoint shall not contain the configured forbidden words. The default list rejects placeholders, examples, non-exhaustive phrasing, fuzzy quantities/timing, and subjective quality terms. Check constructor attributes, including names, descriptions, arguments, comments, verification criteria, collections, and nested metadata. Match whole words/phrases without regard to case. Referenced model entities are checked in their own viewpoint and module scope. KDoc, source comments, generated identities, and enum names are not string attributes.

Corrective action

Replace the reported wording in the named attribute with precise, testable conditions and justified values. Obtain missing engineering decisions before completing the statement.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.requirements.ForbiddenWordsInRequirementRule

Kotlin implementation

com.stigway.metamodels.create.requirements.ForbiddenWordsInRequirementRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/requirements/RequirementRules.kt:

/** Requirements registration of the shared string-value check. */ class ForbiddenWordsInRequirementRule( forbiddenWords: Set<String> = DEFAULT_FORBIDDEN_WORDS, ) : ForbiddenWordsInViewpointRule(Viewpoint.REQUIREMENTS, forbiddenWords) { override val name = "Requirements entity contains forbidden wording" }

com.stigway.metamodels.create.ForbiddenWordsInViewpointRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/ForbiddenWordsRules.kt:

final override fun check(index: ModelIndex): List<ModelProblem> = buildList { for (entity in index.subjectEntities.filter { index.viewpoint(it) == viewpoint }.sortedBy { it.id }) { for ((attribute, text) in modelStringAttributes(entity)) { val found = findForbiddenPhrases(text, phrases) if (found.isEmpty()) continue add( ModelProblem( rule = this@ForbiddenWordsInViewpointRule, severity = defaultSeverity, entityName = entity.id, subjectId = "${entity.id}:$attribute", message = "${entity.idLabel} contains forbidden words in `$attribute`: ${found.joinToString(", ")}.", remediation = "Replace the reported wording in `$attribute` on ${entity.idLabel} with precise, testable " + "conditions: ${found.joinToString(", ")}. Resolve missing engineering decisions " + "before using this text as released evidence.", quickFixes = if ('.' !in attribute && '[' !in attribute) { listOf(RewriteStringArgumentFix(entity.id, attribute, text)) } else emptyList(), ) ) } } }

requirementAllocation

Field

Description

Name

Requirement has no subject element

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH

Contract and evidence

Every requirement shall be allocated to a specific element.

Corrective action

Set the requirement's element to the element responsible for the specified behavior.

Dispatch input

Requirements; once per viewpoint: false.

Kotlin declaration

com.stigway.metamodels.create.requirements.RequirementAllocationRule

Kotlin implementation

com.stigway.metamodels.create.requirements.RequirementAllocationRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/requirements/RequirementRules.kt:

override fun check(container: MetamodelEntity): List<ModelProblem> { val problems = mutableListOf<ModelProblem>() for ((_, req) in container.allRequirements()) { if (req.element.name.isNullOrBlank()) { problems += ModelProblem( rule = this, severity = defaultSeverity, entityName = req.id, message = "${req.idLabel} is allocated to an unnamed element.", remediation = "Replace the unnamed subject element of requirement ${req.idLabel} with the " + "intended named Element reference. The requirement should point at the " + "model element it is actually about.", quickFixes = listOf( PromptSetArgumentFix(req.id, "element", FixValueKind.ELEMENT_REFERENCE), ), ) } } return problems }

requirementAllocatedToDefined

Field

Description

Name

Requirement allocates to no child element

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH

Contract and evidence

A requirement whose element has isBottomLevel=false shall allocate to at least one child declared in its element's Design.children.

Corrective action

Add the responsible child elements from Design.children to the requirement's allocatedTo list. Check the element's bottom-level declaration if no further allocation is in scope.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.requirements.RequirementAllocatedToDefinedRule

Kotlin implementation

com.stigway.metamodels.create.requirements.RequirementAllocatedToDefinedRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/requirements/RequirementRules.kt:

/** * HIGH: Each entry of `Requirement.allocatedTo` must be a *direct child* of the * requirement's subject (`element`), expressing "this requirement, which is about the * subject, is realised by the following sub-elements of it." A requirement cannot * allocate outside its own subject. * * Skips requirements whose `allocatedTo` is empty (no allocation declared). */ class RequirementAllocatedToDefinedRule : RequiredAttributeRule<Requirement>( Requirement::class, Viewpoint.REQUIREMENTS, "allocatedTo", FixValueKind.ELEMENT_REFERENCE, listArgument = true, missing = { !it.element.isBottomLevel && it.allocatedTo.isEmpty() }, ) { override val name = "Requirement allocates to no child element" override val description = "A requirement whose element has isBottomLevel=false shall allocate to at least one child declared in its element's Design.children." override val remediation = "Add the responsible child elements from `Design.children` to the requirement's `allocatedTo` list. " + "Check the element's bottom-level declaration if no further allocation is in scope." }

com.stigway.metamodels.create.RequiredAttributeRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/RequiredAttributeRule.kt:

override fun check(index: ModelIndex): List<ModelProblem> = index.subjectEntities .filter { type.java.isInstance(it) && missing(type.java.cast(it)) } .map { entity -> ModelProblem( rule = this, severity = defaultSeverity, entityName = entity.id, ownerElementId = index.ownerElement(entity)?.id, message = "${entity.idLabel} has no required $attribute value.", remediation = "Set $attribute on ${entity.idLabel} from the model's engineering evidence.", quickFixes = if (valueKind == FixValueKind.MULTIPLICITY) { Multiplicity.entries.map { SetArgumentFix( entity.id, attribute, FixExpression("Multiplicity.${it.name}") ) } } else listOf(PromptSetArgumentFix(entity.id, attribute, valueKind, listArgument = listArgument)), ) }

requirementBottomLevelNoAllocation

Field

Description

Name

Bottom-level requirement allocates to child elements

Contributor unknown

false

Default severity

MODERATE

Possible finding severities

MODERATE

Contract and evidence

An entity on an element with isBottomLevel=true should have no allocatedTo references.

Corrective action

Check the element's isBottomLevel flag against the agreed model scope. If the flag is correct, remove the references in allocatedTo; otherwise correct the flag to match the intended hierarchy.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.RequirementBottomLevelNoAllocationRule

Kotlin implementation

com.stigway.metamodels.create.RequirementBottomLevelNoAllocationRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/BoundaryRules.kt:

class RequirementBottomLevelNoAllocationRule : BoundaryLinksRule<Requirement>( Requirement::class, Viewpoint.REQUIREMENTS, "allocatedTo", "isBottomLevel", { it.element.isBottomLevel && it.allocatedTo.isNotEmpty() }, ) { override val name = "Bottom-level requirement allocates to child elements" }

com.stigway.metamodels.create.BoundaryLinksRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/BoundaryRules.kt:

override fun check(index: ModelIndex): List<ModelProblem> = index.subjectEntities .filter { type.java.isInstance(it) && violates(type.java.cast(it)) } .map { entity -> ModelProblem( this, defaultSeverity, "${entity.idLabel} has $attribute references although its element has $boundary=true.", entityName = entity.id, ownerElementId = index.ownerElement(entity)?.id, remediation = "Review the element's $boundary declaration and the authored $attribute references." ) }

requirementAllocationCoverage

Field

Description

Name

Requirements omit an allocated obligation

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH

Contract and evidence

Every element in a requirement's allocatedTo list shall have a contained requirement derived from it. Coverage is collective across the element's requirements. Missing coverage belongs to every root Requirements specification, or to the element when no specification exists; nested sections are not targets.

Corrective action

Define the child requirement that implements the allocated parent requirement. Set element to the child and add the parent requirement to derivedFrom; place it in that child's Requirements container.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.requirements.RequirementAllocationCoverageRule

Kotlin implementation

com.stigway.metamodels.create.requirements.RequirementAllocationCoverageRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/requirements/RequirementCoverageRules.kt:

override fun check(index: ModelIndex): List<ModelProblem> = buildList { for (child in index.subjectElements) { val parent = child.parent val specifications = index.requirementsRootsOf(child) val targets = specifications.ifEmpty { listOfNotNull(child as? MetamodelEntity) } val allocations = index.requirements.filter { child in it.allocatedTo } index.requireCompleteContent( (listOfNotNull( child, parent ) + allocations.mapNotNull(index::ownerElement)).distinct() ) for (requirement in allocations) { val covered = index.requirementsOf(child).any { it.ownerContainer != null && index.ownerElement(it) === child && requirement in it.derivedFrom } if (covered) continue for (target in targets) add( ModelProblem( rule = this@RequirementAllocationCoverageRule, severity = defaultSeverity, entityName = target.id, ownerElementId = child.id, subjectId = "${target.id}::allocatedRequirement::${requirement.id}", relatedEntityIds = listOf(requirement.id), message = "${target.idLabel} has no requirement covering allocated requirement " + "${requirement.idLabel} for element ${child.idLabel}." + if (specifications.isEmpty()) " Its requirements specification is missing." else "", remediation = "Define a requirement in the requirements specification for ${child.idLabel}, " + "with element referencing that child and derivedFrom referencing ${requirement.idLabel}.", ) ) } } }

requirementAllocatedToChildOfSubject

Field

Description

Name

Requirement allocates outside its subject's design children

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH

Contract and evidence

Each element in Requirement.allocatedTo shall belong to the requirement element's Design.children.

Corrective action

Replace invalid allocatedTo entries with the responsible children declared in the subject element's Design.children, or correct the design decomposition when it omits an actual child.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.requirements.RequirementAllocatedToChildOfSubjectRule

Kotlin implementation

com.stigway.metamodels.create.requirements.RequirementAllocatedToChildOfSubjectRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/requirements/RequirementRules.kt:

override fun check(index: ModelIndex): List<ModelProblem> = index.subjectRequirements.flatMap { req -> if (req.allocatedTo.isEmpty()) return@flatMap emptyList() val subject = req.element index.requireCompleteContent(listOf(subject)) val children = index.designChildrenOf(subject) req.allocatedTo.distinct().filterNot { it in children }.map { allocated -> ModelProblem( rule = this, severity = defaultSeverity, entityName = req.id, ownerElementId = index.ownerElement(req)?.id, relatedEntityIds = listOf(allocated.id), message = "Requirement ${req.idLabel} allocates to ${allocated.idLabel}, which is not listed " + "in Design.children of ${subject.idLabel}.", remediation = "Review the requirement's allocation and its element's declared design decomposition.", quickFixes = listOf( RemoveListItemFix(req.id, "allocatedTo", elementExpr(allocated)), PromptSetArgumentFix(req.id, "allocatedTo", FixValueKind.ELEMENT_REFERENCE, listArgument = true), ), ) } }

designChildAllocation

Field

Description

Name

Parent requirements omit allocation to a design child

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH

Contract and evidence

Every child listed in an element's Design.children shall receive at least one requirement allocation from that element. Missing allocations belong to every root Requirements specification, or to the element when none exists.

Corrective action

Specify the parent's requirements for this child and include the child in their allocatedTo lists. If the child does not belong to this decomposition, correct Design.children.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.requirements.DesignChildAllocationRule

Kotlin implementation

com.stigway.metamodels.create.requirements.DesignChildAllocationRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/requirements/DesignChildAllocationRule.kt:

override fun check(index: ModelIndex): List<ModelProblem> = index.subjectElements.flatMap { element -> index.requireCompleteContent(listOf(element)) val allocated = index.allocatedElements(element) val targets = index.requirementsRootsOf(element).ifEmpty { listOfNotNull(element as? MetamodelEntity) } index.designChildrenOf(element).filterNot { it in allocated }.flatMap { child -> targets.map { target -> ModelProblem( this, defaultSeverity, "${target.idLabel} allocates no requirement to Design child ${child.idLabel} of ${element.idLabel}.", entityName = target.id, ownerElementId = element.id, relatedEntityIds = listOf(child.id), subjectId = "${target.id}.unallocatedChild[${child.id}]", ) } } }

orphanRequirement

Field

Description

Name

Derived requirement cites no parent requirement

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH

Contract and evidence

A requirement whose element has isTopLevel=false shall reference at least one parent requirement through derivedFrom.

Corrective action

Add the parent requirements that justify this obligation to derivedFrom. Check the element's top-level declaration if the obligation has no modeled parent.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.requirements.OrphanRequirementRule

Kotlin implementation

com.stigway.metamodels.create.requirements.OrphanRequirementRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/requirements/RequirementRules.kt:

class OrphanRequirementRule : RequiredAttributeRule<Requirement>( Requirement::class, Viewpoint.REQUIREMENTS, "derivedFrom", FixValueKind.REQUIREMENT_REFERENCE, listArgument = true, missing = { !it.element.isTopLevel && it.derivedFrom.isEmpty() }, ) { override val name = "Derived requirement cites no parent requirement" override val description = "A requirement whose element has isTopLevel=false shall reference at least one parent requirement through derivedFrom." override val remediation = "Add the parent requirements that justify this obligation to `derivedFrom`. " + "Check the element's top-level declaration if the obligation has no modeled parent." }

com.stigway.metamodels.create.RequiredAttributeRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/RequiredAttributeRule.kt:

override fun check(index: ModelIndex): List<ModelProblem> = index.subjectEntities .filter { type.java.isInstance(it) && missing(type.java.cast(it)) } .map { entity -> ModelProblem( rule = this, severity = defaultSeverity, entityName = entity.id, ownerElementId = index.ownerElement(entity)?.id, message = "${entity.idLabel} has no required $attribute value.", remediation = "Set $attribute on ${entity.idLabel} from the model's engineering evidence.", quickFixes = if (valueKind == FixValueKind.MULTIPLICITY) { Multiplicity.entries.map { SetArgumentFix( entity.id, attribute, FixExpression("Multiplicity.${it.name}") ) } } else listOf(PromptSetArgumentFix(entity.id, attribute, valueKind, listArgument = listArgument)), ) }

requirementAsilLeqSubject

Field

Description

Name

Requirement exceeds its subject element's ASIL

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH INFO

Contract and evidence

Each requirement's ASIL shall not exceed its element's ASIL (HIGH on an excessive requirement). A complete nonempty set below the element's ASIL produces INFO on the element. When at least one requirement is present and allocatedAsil is declared, their maximum ASIL shall equal allocatedAsil. Equality is checked when all requirement ASILs and the complete requirement set are available.

Corrective action

Compare the requirement's asil with its subject element's safety classification. Correct the over-classified requirement or under-classified element using the safety allocation evidence. If allocatedAsil is declared, align it with the maximum ASIL of the element's requirements.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.requirements.RequirementAsilLeqSubjectRule

Kotlin implementation

com.stigway.metamodels.create.requirements.RequirementAsilLeqSubjectRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/requirements/RequirementRules.kt:

override fun check(index: ModelIndex): List<ModelProblem> { val problems = mutableListOf<ModelProblem>() val requirementsBySubject = index.requirements.filter { it.ownerContainer != null }.groupBy { it.element } for ((element, requirements) in requirementsBySubject) { val checkedRequirements = requirements.filter(index::isSubject) if (checkedRequirements.isEmpty() && !index.isSubject(element as MetamodelEntity)) continue val maxAsil = requirements.mapNotNull { it.asil }.maxOrNull() ?: continue val subjectAsil = element.asil if (subjectAsil != null && maxAsil > subjectAsil) { for (req in checkedRequirements) { val reqAsil = req.asil ?: continue if (reqAsil <= subjectAsil) continue val identifier = req.idLabel val subjectLabel = req.element.idLabel problems += ModelProblem( rule = this, severity = defaultSeverity, entityName = req.id, message = "Requirement $identifier has ASIL ${reqAsil.name} but its subject element " + "$subjectLabel has ASIL ${subjectAsil.name}. The requirement's ASIL " + "should not exceed its subject's ASIL.", remediation = "Set requirement $identifier to `asil = ASIL.${subjectAsil.name}`. If " + "the requirement is actually about a different element, fix this " + "requirement's `element` reference.", remediationSummary = "Set `asil = ASIL.${subjectAsil.name}` to match the subject element, or correct the requirement's `element` reference.", quickFixes = listOf( SetArgumentFix(req.id, "asil", FixExpression("ASIL.${subjectAsil.name}")), PromptSetArgumentFix(req.id, "element", FixValueKind.ELEMENT_REFERENCE), ), ) } } classificationDifference( this, index, ClassificationValue(element as MetamodelEntity, subjectAsil), requirements.map { ClassificationValue(it, it.asil) }, "ASIL", "requirements", maximum = maxAsil, ) { listOf(element) }?.let(problems::add) val allocatedAsil = element.allocatedAsil ?: continue if (!index.isSubject(element as MetamodelEntity)) continue if (requirements.any { it.asil == null }) continue index.requireCompleteContent(listOf(element)) if (maxAsil == allocatedAsil) continue problems += ModelProblem( rule = this, severity = defaultSeverity, entityName = element.id, ownerElementId = element.id, relatedEntityIds = requirements.map { it.id }.sorted(), message = "${element.idLabel} declares allocatedAsil ${allocatedAsil.name}, but its requirements " + "have maximum ASIL ${maxAsil.name}.", remediationSummary = "Review the requirement classifications and set allocatedAsil on ${element.idLabel} " + "to their justified maximum ASIL ${maxAsil.name}.", quickFixes = listOf( SetArgumentFix(element.id, "allocatedAsil", FixExpression("ASIL.${maxAsil.name}")), ), ) } return problems }

requirementAsilDerivation

Field

Description

Name

Derived requirement falls below a parent requirement's ASIL

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH

Contract and evidence

A derived requirement's ASIL shall be at least the ASIL of every parent in derivedFrom. A lower derived classification is HIGH on that derived requirement. ASIL decomposition is not modeled.

Corrective action

Review the parent and derived requirement classifications against the derivation evidence.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.requirements.RequirementAsilDerivationRule

Kotlin implementation

com.stigway.metamodels.create.requirements.RequirementAsilDerivationRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/requirements/RequirementRules.kt:

override fun check(index: ModelIndex): List<ModelProblem> = buildList { for (derived in index.subjectRequirements.filter { it.ownerContainer != null }) { val limit = derived.asil ?: continue for (parent in derived.derivedFrom.distinct()) { val value = parent.asil ?: continue if (value <= limit) continue add( ModelProblem( this@RequirementAsilDerivationRule, defaultSeverity, "${derived.idLabel} has ASIL ${limit.name}, below parent requirement ${parent.idLabel} ASIL ${value.name}. " + "ASIL decomposition is not modeled.", entityName = derived.id, relatedEntityIds = listOf(parent.id), subjectId = "${derived.id}#parentRequirement:${parent.id}", ) ) } } }

requirementAsilOverclassification

Field

Description

Name

Derived requirement exceeds every parent requirement's ASIL

Contributor unknown

false

Default severity

INFO

Possible finding severities

INFO

Contract and evidence

When every parent requirement is classified, a derived ASIL above their maximum produces INFO on the derived requirement. Equality and unknown or empty parent sets produce no information.

Corrective action

Review whether the higher classification of the derived requirement is intentional.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.requirements.RequirementAsilOverclassificationRule

Kotlin implementation

com.stigway.metamodels.create.requirements.RequirementAsilOverclassificationRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/requirements/RequirementRules.kt:

override fun check(index: ModelIndex): List<ModelProblem> = index.subjectRequirements.mapNotNull { requirement -> classificationDifference( this, index, ClassificationValue(requirement, requirement.asil), requirement.derivedFrom.map { ClassificationValue(it, it.asil) }, "ASIL", "parent requirements", ) { (listOf(requirement) + requirement.derivedFrom).mapNotNull(index::ownerElement) } }

requirementDerivedFromAllocationConsistency

Field

Description

Name

Requirement derives from a parent that does not allocate to its subject

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH

Contract and evidence

For each parent in Requirement.derivedFrom, if the parent declares a non-empty allocatedTo list, the child requirement's subject (element) shall appear in it. A requirement may only derive from a parent that actually allocates to its subject.

Corrective action

Include the child requirement's subject element in the parent requirement's allocatedTo list when that allocation is intended. Otherwise correct the child's derivedFrom links or element reference.

Dispatch input

Requirements; once per viewpoint: false.

Kotlin declaration

com.stigway.metamodels.create.requirements.RequirementDerivedFromAllocationConsistencyRule

Kotlin implementation

com.stigway.metamodels.create.requirements.RequirementDerivedFromAllocationConsistencyRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/requirements/RequirementRules.kt:

override fun check(container: MetamodelEntity): List<ModelProblem> { ModelIndex.current() val problems = mutableListOf<ModelProblem>() val containerAsContainer = container as? Requirements ?: return problems for ((_, req) in containerAsContainer.allRequirements()) { if (req.derivedFrom.isEmpty()) continue val subject = req.element val subjectLabel = subject.idLabel val identifier = req.idLabel for (parent in req.derivedFrom) { if (parent.allocatedTo.isEmpty()) continue if (subject in parent.allocatedTo) continue val parentRef = parent.idLabel val parentAllocLabel = parent.allocatedTo.joinToString(", ") { it.idLabel } problems += ModelProblem( rule = this, severity = defaultSeverity, entityName = req.id, message = "Requirement $identifier (subject $subjectLabel) is derived from " + "$parentRef, but $subjectLabel is not in " + "$parentRef.allocatedTo: $parentAllocLabel. " + "A requirement may only derive from a parent that allocates to its subject.", remediation = "Remove $parentRef from `derivedFrom` on requirement $identifier, or " + "replace it with a parent requirement that allocates to subject " + "$subjectLabel. If this child requirement is actually about one " + "of the parent's allocated elements, fix this requirement's `element` " + "reference to one of: $parentAllocLabel.", quickFixes = listOf(RemoveListItemFix(req.id, "derivedFrom", requirementExpr(parent))) + parent.allocatedTo.map { SetArgumentFix(req.id, "element", elementExpr(it)) }, ) } } return problems }

requirementTopLevelNoParent

Field

Description

Name

Top-level requirement cites a parent requirement

Contributor unknown

false

Default severity

MODERATE

Possible finding severities

MODERATE

Contract and evidence

An entity on an element with isTopLevel=true should have no derivedFrom references.

Corrective action

Check the element's isTopLevel flag against the agreed model scope. If the flag is correct, remove the references in derivedFrom; otherwise correct the flag to match the intended hierarchy.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.requirements.RequirementTopLevelNoParentRule

Kotlin implementation

com.stigway.metamodels.create.requirements.RequirementTopLevelNoParentRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/requirements/RequirementRules.kt:

class RequirementTopLevelNoParentRule : BoundaryLinksRule<Requirement>( Requirement::class, Viewpoint.REQUIREMENTS, "derivedFrom", "isTopLevel", { it.element.isTopLevel && it.derivedFrom.isNotEmpty() }, ) { override val name = "Top-level requirement cites a parent requirement" }

com.stigway.metamodels.create.BoundaryLinksRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/BoundaryRules.kt:

override fun check(index: ModelIndex): List<ModelProblem> = index.subjectEntities .filter { type.java.isInstance(it) && violates(type.java.cast(it)) } .map { entity -> ModelProblem( this, defaultSeverity, "${entity.idLabel} has $attribute references although its element has $boundary=true.", entityName = entity.id, ownerElementId = index.ownerElement(entity)?.id, remediation = "Review the element's $boundary declaration and the authored $attribute references." ) }

Design

safetyMeasureMustLiveInDesign

Field

Description

Name

Safety measure lacks a containing design

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH

Contract and evidence

Every safety measure, including subclasses, shall be declared as a named property in a Design. Nested designs are allowed; failures may reference measures from another element's design.

Corrective action

Move the named safety-measure declaration into its owning element's Design. Preserve the references from failures, including those in other elements.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.design.SafetyMeasureMustLiveInDesignRule

Kotlin implementation

com.stigway.metamodels.create.design.SafetyMeasureMustLiveInDesignRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/design/SafetyMeasureRules.kt:

override fun check(index: ModelIndex): List<ModelProblem> = index.subjectEntities.filterIsInstance<SafetyMeasure>().filter { index.declarationParent(it) !is Design }.map { ModelProblem( this, defaultSeverity, "Safety measure ${it.idLabel} is not declared in a Design.", entityName = it.id, ) }

nonDesignEntityInDesignPackage

Field

Description

Name

Entity uses the wrong viewpoint package (Design)

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH

Contract and evidence

A file under a .design package may only declare design-viewpoint entities (Design and SafetyMeasure subclasses).

Corrective action

Move the declaration out of .design into the viewpoint package appropriate for its entity type.

Dispatch input

MetamodelEntity; once per viewpoint: true.

Kotlin declaration

com.stigway.metamodels.create.NonDesignEntityInDesignPackageRule

Kotlin implementation

com.stigway.metamodels.create.NonDesignEntityInDesignPackageRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/ViewpointPackageRules.kt:

override fun check(container: MetamodelEntity): List<ModelProblem> = buildFindingsForViewpoint(this, Viewpoint.DESIGN, "design")

designClassesTopLevel

Field

Description

Name

Design class is nested inside another declaration

Contributor unknown

false

Default severity

MODERATE

Possible finding severities

MODERATE

Contract and evidence

Every class declared in this viewpoint shall be directly in its Kotlin file, outside other classes, objects and functions.

Corrective action

Move the class to file scope in the same Kotlin file. Update type references and pass any required enclosing state explicitly; retain the model's object containment.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.DesignClassesTopLevelRule

Kotlin implementation

com.stigway.metamodels.create.DesignClassesTopLevelRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/ViewpointDeclarationRules.kt:

class DesignClassesTopLevelRule : ViewpointClassesTopLevelRule(Viewpoint.DESIGN) { override val name = "Design class is nested inside another declaration" }

com.stigway.metamodels.create.ViewpointClassesTopLevelRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/ViewpointDeclarationRules.kt:

override fun check(index: ModelIndex): List<ModelProblem> = index.sourceFindings(this) { _, declaration -> if (declaration.kind == KotlinDeclarationKind.CLASS && !declaration.topLevel) "Class [${declaration.qualifiedName}] is nested; it shall be declared at file scope." else null }

designClassInstance

Field

Description

Name

Design class has no instance property in its file

Contributor unknown

false

Default severity

MODERATE

Possible finding severities

MODERATE

Contract and evidence

Every concrete class in this viewpoint shall have at least one instance property in the same Kotlin file, either at file scope or as a member of a class or object. Multiple instances are allowed. Function-local variables do not satisfy this obligation. Abstract, sealed, enum, annotation and expect classes and interfaces are exempt.

Corrective action

Declare an instance property in the same Kotlin file (for example, val abc = ABC()), either at file scope or as a field of its owning model class or object. Keep member instances in their owning container; multiple instances of the same class are allowed.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.DesignClassInstanceRule

Kotlin implementation

com.stigway.metamodels.create.DesignClassInstanceRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/ViewpointDeclarationRules.kt:

class DesignClassInstanceRule : ViewpointClassInstanceRule(Viewpoint.DESIGN) { override val name = "Design class has no instance property in its file" }

com.stigway.metamodels.create.ViewpointClassInstanceRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/ViewpointDeclarationRules.kt:

override fun check(index: ModelIndex): List<ModelProblem> { val counts = index.sourceFiles.filter { it.viewpoint == viewpoint }.associateWith { source -> val classes = source.declarations.filter { it.kind == KotlinDeclarationKind.CLASS } .mapTo(hashSetOf()) { it.qualifiedName } source.declarations.filter { it.kind == KotlinDeclarationKind.PROPERTY && (it.topLevel || it.memberProperty) } .mapNotNull { property -> val constructed = property.constructedType?.let { source.typeName(it, property) } constructed?.takeIf { it in classes } ?: property.declaredType?.let { source.typeName(it, property) } }.groupingBy { it }.eachCount() } return index.sourceFindings(this) { source, declaration -> if (!declaration.concrete) return@sourceFindings null val instances = counts.getValue(source)[declaration.qualifiedName] ?: 0 if (instances > 0) null else "Class [${declaration.qualifiedName}] has no instance property in this file; declare one at file scope or as a member of its owning class or object." } }

designClassPascalCase

Field

Description

Name

Design class name violates PascalCase

Contributor unknown

false

Default severity

MODERATE

Possible finding severities

MODERATE

Contract and evidence

Class identifiers in this viewpoint shall start with an uppercase letter and contain only letters and digits (PascalCase).

Corrective action

Rename the class to PascalCase with the IDE's Rename refactoring, removing underscores and dashes, and update every type and constructor reference.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.DesignClassPascalCaseRule

Kotlin implementation

com.stigway.metamodels.create.DesignClassPascalCaseRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/ViewpointDeclarationRules.kt:

class DesignClassPascalCaseRule : ViewpointClassPascalCaseRule(Viewpoint.DESIGN) { override val name = "Design class name violates PascalCase" }

com.stigway.metamodels.create.ViewpointClassPascalCaseRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/ViewpointDeclarationRules.kt:

override fun check(index: ModelIndex): List<ModelProblem> = index.sourceFindings(this) { _, declaration -> if (declaration.kind == KotlinDeclarationKind.CLASS && !ModelDeclarationNames.pascalCase(declaration.name)) "Class [${declaration.qualifiedName}] is not PascalCase." else null }

designObjectCamelCase

Field

Description

Name

Design instance name violates camelCase

Contributor unknown

false

Default severity

MODERATE

Possible finding severities

MODERATE

Contract and evidence

Instance property and named object identifiers in this viewpoint shall start with a lowercase letter and contain only letters and digits (camelCase). Context declarations of ProvidedMethod and RequiredMethod, including derived types, retain the external API identifier.

Corrective action

Rename the property or named object to camelCase with the IDE's Rename refactoring, removing underscores and dashes. Update references and any configured or persisted model IDs affected by the rename.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.DesignObjectCamelCaseRule

Kotlin implementation

com.stigway.metamodels.create.DesignObjectCamelCaseRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/ViewpointDeclarationRules.kt:

class DesignObjectCamelCaseRule : ViewpointObjectCamelCaseRule(Viewpoint.DESIGN) { override val name = "Design instance name violates camelCase" }

com.stigway.metamodels.create.ViewpointObjectCamelCaseRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/ViewpointDeclarationRules.kt:

override fun check(index: ModelIndex): List<ModelProblem> { val externalMethods = if (viewpoint == Viewpoint.CONTEXT) index.directMethodDeclarations() else emptySet() return index.sourceFindings(this) { _, declaration -> if (declaration.kind in setOf(KotlinDeclarationKind.PROPERTY, KotlinDeclarationKind.OBJECT) && declaration.qualifiedName !in externalMethods && !ModelDeclarationNames.camelCase(declaration.name) ) "Object [${declaration.qualifiedName}] is not camelCase." else null } }

nameDefinedInDesignPackage

Field

Description

Name

Design entity has no required name

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH

Contract and evidence

Every design entity shall have a non-blank name.

Corrective action

Give the design entity a short domain name in its name.

Dispatch input

MetamodelEntity; once per viewpoint: true.

Kotlin declaration

com.stigway.metamodels.create.NameDefinedInDesignPackageRule

Kotlin implementation

com.stigway.metamodels.create.NameDefinedInDesignPackageRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/MetamodelPresenceRules.kt:

override fun check(container: MetamodelEntity): List<ModelProblem> = missingNameFindings(this, Viewpoint.DESIGN)

descriptionDefinedInDesignPackage

Field

Description

Name

Design entity has no required description

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH

Contract and evidence

Every design entity except Design shall have a non-blank description. Design descriptions are optional.

Corrective action

Describe the design entity's responsibility and how it contributes to the design in its description.

Dispatch input

MetamodelEntity; once per viewpoint: true.

Kotlin declaration

com.stigway.metamodels.create.DescriptionDefinedInDesignPackageRule

Kotlin implementation

com.stigway.metamodels.create.DescriptionDefinedInDesignPackageRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/MetamodelPresenceRules.kt:

override fun check(container: MetamodelEntity): List<ModelProblem> = missingDescriptionFindings(this, Viewpoint.DESIGN)

designElementDefined

Field

Description

Name

Design has no subject element

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH

Contract and evidence

Every Design shall define its required element attribute.

Corrective action

Set the element of Design using the applicable engineering evidence.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.design.DesignElementDefinedRule

Kotlin implementation

com.stigway.metamodels.create.design.DesignElementDefinedRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/design/DesignRules.kt:

class DesignElementDefinedRule : RequiredAttributeRule<Design>( Design::class, Viewpoint.DESIGN, "element", FixValueKind.ELEMENT_REFERENCE, missing = { ModelIndex.current().ownerElement(it) == null }, ) { override val name = "Design has no subject element" }

com.stigway.metamodels.create.RequiredAttributeRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/RequiredAttributeRule.kt:

override fun check(index: ModelIndex): List<ModelProblem> = index.subjectEntities .filter { type.java.isInstance(it) && missing(type.java.cast(it)) } .map { entity -> ModelProblem( rule = this, severity = defaultSeverity, entityName = entity.id, ownerElementId = index.ownerElement(entity)?.id, message = "${entity.idLabel} has no required $attribute value.", remediation = "Set $attribute on ${entity.idLabel} from the model's engineering evidence.", quickFixes = if (valueKind == FixValueKind.MULTIPLICITY) { Multiplicity.entries.map { SetArgumentFix( entity.id, attribute, FixExpression("Multiplicity.${it.name}") ) } } else listOf(PromptSetArgumentFix(entity.id, attribute, valueKind, listArgument = listArgument)), ) }

safetyMechanismAsilDefined

Field

Description

Name

Safety mechanism has no ASIL

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH

Contract and evidence

Every SafetyMechanism shall define its required asil attribute.

Corrective action

Set the asil of SafetyMechanism using the applicable engineering evidence.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.design.SafetyMechanismAsilDefinedRule

Kotlin implementation

com.stigway.metamodels.create.design.SafetyMechanismAsilDefinedRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/design/DesignRules.kt:

class SafetyMechanismAsilDefinedRule : RequiredAttributeRule<SafetyMechanism>( SafetyMechanism::class, Viewpoint.DESIGN, "asil", FixValueKind.ASIL, missing = { it.asil == null }, ) { override val name = "Safety mechanism has no ASIL" }

com.stigway.metamodels.create.RequiredAttributeRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/RequiredAttributeRule.kt:

override fun check(index: ModelIndex): List<ModelProblem> = index.subjectEntities .filter { type.java.isInstance(it) && missing(type.java.cast(it)) } .map { entity -> ModelProblem( rule = this, severity = defaultSeverity, entityName = entity.id, ownerElementId = index.ownerElement(entity)?.id, message = "${entity.idLabel} has no required $attribute value.", remediation = "Set $attribute on ${entity.idLabel} from the model's engineering evidence.", quickFixes = if (valueKind == FixValueKind.MULTIPLICITY) { Multiplicity.entries.map { SetArgumentFix( entity.id, attribute, FixExpression("Multiplicity.${it.name}") ) } } else listOf(PromptSetArgumentFix(entity.id, attribute, valueKind, listArgument = listArgument)), ) }

safetyMeasureAsilDefined

Field

Description

Name

Safety measure has no ASIL

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH

Contract and evidence

Every SafetyMeasure shall define its required asil attribute.

Corrective action

Set the asil of SafetyMeasure using the applicable engineering evidence.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.SafetyMeasureAsilDefinedRule

Kotlin implementation

com.stigway.metamodels.create.SafetyMeasureAsilDefinedRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/RequiredAttributeRule.kt:

class SafetyMeasureAsilDefinedRule : RequiredAttributeRule<SafetyMeasure>( SafetyMeasure::class, Viewpoint.DESIGN, "asil", FixValueKind.ASIL, missing = { it !is SafetyMechanism && it.asil == null }, ) { override val name = "Safety measure has no ASIL" }

com.stigway.metamodels.create.RequiredAttributeRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/RequiredAttributeRule.kt:

override fun check(index: ModelIndex): List<ModelProblem> = index.subjectEntities .filter { type.java.isInstance(it) && missing(type.java.cast(it)) } .map { entity -> ModelProblem( rule = this, severity = defaultSeverity, entityName = entity.id, ownerElementId = index.ownerElement(entity)?.id, message = "${entity.idLabel} has no required $attribute value.", remediation = "Set $attribute on ${entity.idLabel} from the model's engineering evidence.", quickFixes = if (valueKind == FixValueKind.MULTIPLICITY) { Multiplicity.entries.map { SetArgumentFix( entity.id, attribute, FixExpression("Multiplicity.${it.name}") ) } } else listOf(PromptSetArgumentFix(entity.id, attribute, valueKind, listArgument = listArgument)), ) }

forbiddenWordsInDesign

Field

Description

Name

Design entity contains forbidden wording

Contributor unknown

false

Default severity

MODERATE

Possible finding severities

MODERATE

Contract and evidence

String attributes in the design viewpoint shall not contain the configured forbidden words. The default list only rejects explicit unfinished-work markers: tbd, tbc, todo, fixme. Narrative failure descriptions and assessment arguments may use uncertainty and qualitative wording. Check constructor attributes, including names, descriptions, arguments, comments, verification criteria, collections, and nested metadata. Match whole words/phrases without regard to case. Referenced model entities are checked in their own viewpoint and module scope. KDoc, source comments, generated identities, and enum names are not string attributes.

Corrective action

Replace the reported wording in the named attribute with precise, testable conditions and justified values. Obtain missing engineering decisions before completing the statement.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.ForbiddenWordsInDesignRule

Kotlin implementation

com.stigway.metamodels.create.ForbiddenWordsInDesignRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/ForbiddenWordsRules.kt:

class ForbiddenWordsInDesignRule : ForbiddenWordsInViewpointRule(Viewpoint.DESIGN) { override val name = "Design entity contains forbidden wording" }

com.stigway.metamodels.create.ForbiddenWordsInViewpointRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/ForbiddenWordsRules.kt:

final override fun check(index: ModelIndex): List<ModelProblem> = buildList { for (entity in index.subjectEntities.filter { index.viewpoint(it) == viewpoint }.sortedBy { it.id }) { for ((attribute, text) in modelStringAttributes(entity)) { val found = findForbiddenPhrases(text, phrases) if (found.isEmpty()) continue add( ModelProblem( rule = this@ForbiddenWordsInViewpointRule, severity = defaultSeverity, entityName = entity.id, subjectId = "${entity.id}:$attribute", message = "${entity.idLabel} contains forbidden words in `$attribute`: ${found.joinToString(", ")}.", remediation = "Replace the reported wording in `$attribute` on ${entity.idLabel} with precise, testable " + "conditions: ${found.joinToString(", ")}. Resolve missing engineering decisions " + "before using this text as released evidence.", quickFixes = if ('.' !in attribute && '[' !in attribute) { listOf(RewriteStringArgumentFix(entity.id, attribute, text)) } else emptyList(), ) ) } } }

safetyMechanismAsilExceedsElement

Field

Description

Name

Safety mechanism exceeds its element's ASIL

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH INFO

Contract and evidence

A safety mechanism's ASIL shall not exceed its element's ASIL (HIGH on the mechanism). A complete nonempty set below the element's ASIL produces INFO on the element.

Corrective action

Review the safety mechanisms against their design's owning element.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.design.SafetyMechanismAsilExceedsElementRule

Kotlin implementation

com.stigway.metamodels.create.design.SafetyMechanismAsilExceedsElementRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/design/DesignRules.kt:

override fun check(index: ModelIndex): List<ModelProblem> = buildList { val groups = index.entities.filterIsInstance<SafetyMechanism>().groupBy(index::ownerElement) for ((element, mechanisms) in groups) { val limit = element?.asil ?: continue for (mechanism in mechanisms.filter(index::isSubject)) { val value = mechanism.asil ?: continue if (value <= limit) continue add( ModelProblem( this@SafetyMechanismAsilExceedsElementRule, defaultSeverity, "Safety mechanism ${mechanism.idLabel} has ASIL ${value.name} which exceeds element " + "${element.idLabel} ASIL ${limit.name}.", entityName = mechanism.id, remediation = "Review the classification of ${mechanism.idLabel} against ${element.idLabel}.", remediationSummary = "Review the safety mechanism's ASIL against its owning element's ASIL ${limit.name}.", quickFixes = listOf(SetArgumentFix(mechanism.id, "asil", FixExpression("ASIL.${limit.name}"))), ) ) } classificationDifference( this@SafetyMechanismAsilExceedsElementRule, index, ClassificationValue(element as MetamodelEntity, limit), mechanisms.map { ClassificationValue(it, it.asil) }, "ASIL", "safety mechanisms", ) { listOf(element) }?.let(::add) } }

designChildrenParent

Field

Description

Name

Design lists a child with a different parent

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH

Contract and evidence

Every element listed in Design.children shall have the design's owning element as its parent.

Corrective action

Set each declared child's parent to the design's owning element, or remove an incorrectly listed child from Design.children and place it in its actual parent's design.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.design.DesignChildrenParentRule

Kotlin implementation

com.stigway.metamodels.create.design.DesignChildrenParentRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/design/DesignDecompositionRules.kt:

override fun check(index: ModelIndex): List<ModelProblem> = index.designs.filter(index::isSubject).flatMap { design -> val element = index.ownerElement(design) ?: return@flatMap emptyList() design.children.distinct().filter { it === element || it.parent !== element }.map { child -> ModelProblem( this, defaultSeverity, "${design.idLabel} lists ${child.idLabel} as a child, but its parent is not ${element.idLabel}.", entityName = design.id, ownerElementId = element.id, relatedEntityIds = listOf(child.id), remediation = "Review the design's children and each child's authored parent.", ) } }

designChildrenBoundary

Field

Description

Name

Design contradicts the element's bottom-level declaration

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH

Contract and evidence

An element with isBottomLevel=true shall have no Design.children; an element with isBottomLevel=false shall have at least one Design child.

Corrective action

Align isBottomLevel with the agreed decomposition: list the child elements in Design.children when decomposing further, or remove child declarations when this is the lowest modeled level.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.design.DesignChildrenBoundaryRule

Kotlin implementation

com.stigway.metamodels.create.design.DesignChildrenBoundaryRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/design/DesignDecompositionRules.kt:

override fun check(index: ModelIndex): List<ModelProblem> = index.subjectElements.flatMap { element -> index.requireCompleteContent(listOf(element)) val children = index.designChildrenOf(element) if (element.isBottomLevel == children.isEmpty()) return@flatMap emptyList() val targets: List<MetamodelEntity> = if (element.isBottomLevel) { index.designsOf(element).filter { it.children.isNotEmpty() } } else listOf(element as MetamodelEntity) targets.map { target -> ModelProblem( this, defaultSeverity, if (element.isBottomLevel) "${target.idLabel} declares children although ${element.idLabel} has isBottomLevel=true." else "${element.idLabel} has isBottomLevel=false but declares no Design.children.", entityName = target.id, ownerElementId = element.id, relatedEntityIds = (if (target is Design) target.children else children).distinct().map { it.id }, remediation = "Review the element's isBottomLevel declaration and its Design.children.", ) } }

Analysis

failureMustLiveInInterfacePointAnalysis

Field

Description

Name

Failure lacks a containing interface-point analysis

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH

Contract and evidence

Every Failure shall be declared as a property of an InterfacePointAnalysis subclass; top-level val xxx = Failure(...) declarations are not allowed.

Corrective action

Move the failure into its owning InterfacePointAnalysis subclass as a named val property, preserving its attributes and propagation references.

Dispatch input

MetamodelEntity; once per viewpoint: true.

Kotlin declaration

com.stigway.metamodels.create.analysis.FailureMustLiveInInterfacePointAnalysisRule

Kotlin implementation

com.stigway.metamodels.create.analysis.FailureMustLiveInInterfacePointAnalysisRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/analysis/AnalysisRules.kt:

override fun check(container: MetamodelEntity): List<ModelProblem> { return ModelIndex.current().subjectEntities .filterIsInstance<Failure>() .filter { it.ownerInterfacePointAnalysis == null } .map { failure -> val ref = failure.idLabel val site = failure.declaringClassName ?: "(unknown declaring class)" ModelProblem( rule = this, severity = defaultSeverity, entityName = failure.id, message = "Failure $ref is not declared inside any InterfacePointAnalysis " + "(declared at: $site). Move it into an `InterfacePointAnalysis` subclass " + "as a `val` property.", remediation = "Move failure $ref into the owning InterfacePointAnalysis as a `val` " + "property. Keep the failure data unchanged unless the free-floating " + "declaration itself is the wrong failure.", quickFixes = listOf( MoveDeclarationFix(failure.id, MoveTargetKind.INTERFACE_POINT_ANALYSIS), ), ) } }

interfacePointAnalysisMustLiveInElementAnalysis

Field

Description

Name

Interface-point analysis lacks a containing element analysis

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH

Contract and evidence

Every InterfacePointAnalysis shall be declared directly or through nested interface-point analyses inside an Analysis subclass; top-level val xxx = SomeIpaSubclass() declarations are not allowed.

Corrective action

Declare the interface-point analysis as a named val property inside the owning element's Analysis subclass or inside its enclosing port or service-group analysis.

Dispatch input

MetamodelEntity; once per viewpoint: true.

Kotlin declaration

com.stigway.metamodels.create.analysis.InterfacePointAnalysisMustLiveInElementAnalysisRule

Kotlin implementation

com.stigway.metamodels.create.analysis.InterfacePointAnalysisMustLiveInElementAnalysisRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/analysis/AnalysisRules.kt:

override fun check(container: MetamodelEntity): List<ModelProblem> { return ModelIndex.current().subjectEntities .filterIsInstance<InterfacePointAnalysis>() .filter { it.ownerAnalysis == null } .map { interfacePointAnalysis -> val ref = interfacePointAnalysis.idLabel val site = interfacePointAnalysis.declaringClassName ?: "(unknown declaring class)" ModelProblem( rule = this, severity = defaultSeverity, entityName = interfacePointAnalysis.id, message = "InterfacePointAnalysis $ref is not declared inside any Analysis " + "(declared at: $site). Move it into an `Analysis` subclass " + "as a `val` property.", remediation = "Move interface-point analysis $ref into the owning Analysis as a " + "`val` property. Keep the analysis data unchanged unless the " + "free-floating declaration itself is the wrong analysis.", quickFixes = listOf( MoveDeclarationFix(interfacePointAnalysis.id, MoveTargetKind.ELEMENT_ANALYSIS), ), ) } }

nonAnalysisEntityInAnalysisPackage

Field

Description

Name

Entity uses the wrong viewpoint package (Analysis)

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH

Contract and evidence

A file under an .analysis package may only declare analysis-viewpoint entities (Failure, InterfacePointAnalysis, Analysis).

Corrective action

Move the declaration out of .analysis into the viewpoint package appropriate for its entity type.

Dispatch input

MetamodelEntity; once per viewpoint: true.

Kotlin declaration

com.stigway.metamodels.create.NonAnalysisEntityInAnalysisPackageRule

Kotlin implementation

com.stigway.metamodels.create.NonAnalysisEntityInAnalysisPackageRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/ViewpointPackageRules.kt:

override fun check(container: MetamodelEntity): List<ModelProblem> = buildFindingsForViewpoint(this, Viewpoint.ANALYSIS, "analysis")

analysisClassesTopLevel

Field

Description

Name

Analysis class is nested inside another declaration

Contributor unknown

false

Default severity

MODERATE

Possible finding severities

MODERATE

Contract and evidence

Every class declared in this viewpoint shall be directly in its Kotlin file, outside other classes, objects and functions.

Corrective action

Move the class to file scope in the same Kotlin file. Update type references and pass any required enclosing state explicitly; retain the model's object containment.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.AnalysisClassesTopLevelRule

Kotlin implementation

com.stigway.metamodels.create.AnalysisClassesTopLevelRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/ViewpointDeclarationRules.kt:

class AnalysisClassesTopLevelRule : ViewpointClassesTopLevelRule(Viewpoint.ANALYSIS) { override val name = "Analysis class is nested inside another declaration" }

com.stigway.metamodels.create.ViewpointClassesTopLevelRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/ViewpointDeclarationRules.kt:

override fun check(index: ModelIndex): List<ModelProblem> = index.sourceFindings(this) { _, declaration -> if (declaration.kind == KotlinDeclarationKind.CLASS && !declaration.topLevel) "Class [${declaration.qualifiedName}] is nested; it shall be declared at file scope." else null }

analysisClassInstance

Field

Description

Name

Analysis class has no instance property in its file

Contributor unknown

false

Default severity

MODERATE

Possible finding severities

MODERATE

Contract and evidence

Every concrete class in this viewpoint shall have at least one instance property in the same Kotlin file, either at file scope or as a member of a class or object. Multiple instances are allowed. Function-local variables do not satisfy this obligation. Abstract, sealed, enum, annotation and expect classes and interfaces are exempt.

Corrective action

Declare an instance property in the same Kotlin file (for example, val abc = ABC()), either at file scope or as a field of its owning model class or object. Keep member instances in their owning container; multiple instances of the same class are allowed.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.AnalysisClassInstanceRule

Kotlin implementation

com.stigway.metamodels.create.AnalysisClassInstanceRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/ViewpointDeclarationRules.kt:

class AnalysisClassInstanceRule : ViewpointClassInstanceRule(Viewpoint.ANALYSIS) { override val name = "Analysis class has no instance property in its file" }

com.stigway.metamodels.create.ViewpointClassInstanceRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/ViewpointDeclarationRules.kt:

override fun check(index: ModelIndex): List<ModelProblem> { val counts = index.sourceFiles.filter { it.viewpoint == viewpoint }.associateWith { source -> val classes = source.declarations.filter { it.kind == KotlinDeclarationKind.CLASS } .mapTo(hashSetOf()) { it.qualifiedName } source.declarations.filter { it.kind == KotlinDeclarationKind.PROPERTY && (it.topLevel || it.memberProperty) } .mapNotNull { property -> val constructed = property.constructedType?.let { source.typeName(it, property) } constructed?.takeIf { it in classes } ?: property.declaredType?.let { source.typeName(it, property) } }.groupingBy { it }.eachCount() } return index.sourceFindings(this) { source, declaration -> if (!declaration.concrete) return@sourceFindings null val instances = counts.getValue(source)[declaration.qualifiedName] ?: 0 if (instances > 0) null else "Class [${declaration.qualifiedName}] has no instance property in this file; declare one at file scope or as a member of its owning class or object." } }

analysisClassPascalCase

Field

Description

Name

Analysis class name violates PascalCase

Contributor unknown

false

Default severity

MODERATE

Possible finding severities

MODERATE

Contract and evidence

Class identifiers in this viewpoint shall start with an uppercase letter and contain only letters and digits (PascalCase).

Corrective action

Rename the class to PascalCase with the IDE's Rename refactoring, removing underscores and dashes, and update every type and constructor reference.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.AnalysisClassPascalCaseRule

Kotlin implementation

com.stigway.metamodels.create.AnalysisClassPascalCaseRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/ViewpointDeclarationRules.kt:

class AnalysisClassPascalCaseRule : ViewpointClassPascalCaseRule(Viewpoint.ANALYSIS) { override val name = "Analysis class name violates PascalCase" }

com.stigway.metamodels.create.ViewpointClassPascalCaseRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/ViewpointDeclarationRules.kt:

override fun check(index: ModelIndex): List<ModelProblem> = index.sourceFindings(this) { _, declaration -> if (declaration.kind == KotlinDeclarationKind.CLASS && !ModelDeclarationNames.pascalCase(declaration.name)) "Class [${declaration.qualifiedName}] is not PascalCase." else null }

analysisObjectCamelCase

Field

Description

Name

Analysis instance name violates camelCase

Contributor unknown

false

Default severity

MODERATE

Possible finding severities

MODERATE

Contract and evidence

Instance property and named object identifiers in this viewpoint shall start with a lowercase letter and contain only letters and digits (camelCase). Context declarations of ProvidedMethod and RequiredMethod, including derived types, retain the external API identifier.

Corrective action

Rename the property or named object to camelCase with the IDE's Rename refactoring, removing underscores and dashes. Update references and any configured or persisted model IDs affected by the rename.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.AnalysisObjectCamelCaseRule

Kotlin implementation

com.stigway.metamodels.create.AnalysisObjectCamelCaseRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/ViewpointDeclarationRules.kt:

class AnalysisObjectCamelCaseRule : ViewpointObjectCamelCaseRule(Viewpoint.ANALYSIS) { override val name = "Analysis instance name violates camelCase" }

com.stigway.metamodels.create.ViewpointObjectCamelCaseRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/ViewpointDeclarationRules.kt:

override fun check(index: ModelIndex): List<ModelProblem> { val externalMethods = if (viewpoint == Viewpoint.CONTEXT) index.directMethodDeclarations() else emptySet() return index.sourceFindings(this) { _, declaration -> if (declaration.kind in setOf(KotlinDeclarationKind.PROPERTY, KotlinDeclarationKind.OBJECT) && declaration.qualifiedName !in externalMethods && !ModelDeclarationNames.camelCase(declaration.name) ) "Object [${declaration.qualifiedName}] is not camelCase." else null } }

interfacePointAnalysisName

Field

Description

Name

Analysis declaration violates the Analysis naming convention

Contributor unknown

false

Default severity

MODERATE

Possible finding severities

MODERATE

Contract and evidence

Classes and instances derived from Analysis or InterfacePointAnalysis shall end with Analysis. InterfacePointAnalysis declarations shall use the referenced interface point identifier in PascalCase for classes or camelCase for instances, without separators. Acronym casing may follow the authored Kotlin spelling. The referenced or enclosing element prefix is permitted to disambiguate shared packages and member names.

Corrective action

Use the Analysis suffix for every analysis class and instance. For interface-point analyses, normalize the point identifier and optionally prefix the owning element. Update symbol references while preserving the original interfacePoint binding.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.analysis.InterfacePointAnalysisNameRule

Kotlin implementation

com.stigway.metamodels.create.analysis.InterfacePointAnalysisNameRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/analysis/InterfacePointAnalysisNameRule.kt:

override fun check(index: ModelIndex): List<ModelProblem> { val sources = index.contextSourceFiles val classes = sources.flatMap { source -> source.declarations.filter { it.kind != KotlinDeclarationKind.PROPERTY } .map { it.qualifiedName to (source to it) } }.toMap() val pointAnalysisType = "com.stigway.metamodels.highway.InterfacePointAnalysis" val elementAnalysisType = "com.stigway.metamodels.highway.Analysis" val knownTypes = classes.keys + setOf(pointAnalysisType, elementAnalysisType) fun expand(source: KotlinModelSource, reference: String): String { val first = reference.substringBefore('.') return source.imports[first]?.let { it + reference.removePrefix(first) } ?: reference } data class Target(val point: Boolean, val reference: String?) fun point(source: KotlinModelSource, declaration: KotlinModelDeclaration, seen: MutableSet<String>): Target? { if (!seen.add(declaration.qualifiedName)) return null val types = if (declaration.kind == KotlinDeclarationKind.PROPERTY) listOfNotNull( declaration.constructedType, declaration.declaredType ).distinct() else declaration.superTypes for (type in types) { val resolved = source.typeName(type, declaration, knownTypes) val direct = when (resolved) { pointAnalysisType -> Target(true, null) elementAnalysisType -> Target(false, null) else -> null } val inherited = direct ?: classes[resolved]?.let { (parentSource, parent) -> point(parentSource, parent, seen) } ?: continue val arguments = declaration.constructorCalls[type].orEmpty() val named = arguments.firstOrNull { it.name == if (inherited.point) "interfacePoint" else "element" } val reference = (named ?: arguments.getOrNull(if (inherited.point) 1 else 3) ?.takeIf { direct != null && it.name == null }) ?.reference?.takeUnless { it.substringBefore('.') in declaration.constructorParameters } ?.let { expand(source, it) } return if (direct != null || named != null) inherited.copy(reference = reference) else inherited } return null } val instances = sources.flatMap { source -> source.declarations.filter { it.kind == KotlinDeclarationKind.PROPERTY }.flatMap { declaration -> listOfNotNull(declaration.constructedType, declaration.declaredType).distinct().map { type -> source.typeName(type, declaration, knownTypes) to (source to declaration) } } }.groupBy({ it.first }, { it.second }) // Top-level point-analysis classes obtain their owning element from their instance containment. fun enclosingElements( source: KotlinModelSource, declaration: KotlinModelDeclaration, seen: Set<String> = emptySet(), ): Set<String> { if (declaration.qualifiedName in seen) return emptySet() val visited = seen + declaration.qualifiedName val target = point(source, declaration, mutableSetOf()) if (target != null && !target.point) return setOfNotNull(target.reference?.substringAfterLast('.')) val parent = classes[declaration.qualifiedName.substringBeforeLast('.', "")] if (parent != null) return enclosingElements(parent.first, parent.second, visited) return instances[declaration.qualifiedName].orEmpty().flatMap { (instanceSource, instance) -> enclosingElements(instanceSource, instance, visited) }.toSet() } return index.sourceFindings(this) { source, declaration -> val target = point(source, declaration, mutableSetOf()) ?: return@sourceFindings null if (!target.point) return@sourceFindings if (declaration.name.endsWith("Analysis")) null else "Analysis declaration [${declaration.qualifiedName}] shall end with Analysis." val reference = target.reference ?: return@sourceFindings if (declaration.name.endsWith("Analysis")) null else "Analysis declaration [${declaration.qualifiedName}] shall end with Analysis. Its interface point is supplied by an expression or constructor parameter; use that point's identifier as the name prefix when it is bound." val expected = ModelReferenceNames.expectedInterfacePointAnalysisType(reference) val actual = declaration.name.replaceFirstChar(Char::uppercaseChar) val referencedOwner = reference.substringAfter(".context.").substringBefore('.').takeIf { '.' in reference } val owners = (enclosingElements(source, declaration) + listOfNotNull(referencedOwner)) .map(ModelDeclarationNames::pascalName) if (declaration.name.endsWith("Analysis") && (actual.equals(expected, ignoreCase = true) || owners.any { actual.equals( it + expected, ignoreCase = true ) }) ) null else "Analysis declaration [${declaration.qualifiedName}] shall be named ${ if (declaration.kind == KotlinDeclarationKind.CLASS) expected else expected.replaceFirstChar( Char::lowercaseChar ) } after interface point $reference." } }

nameDefinedInAnalysisPackage

Field

Description

Name

Analysis entity has no required name

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH

Contract and evidence

Every analysis entity except InterfacePointAnalysis shall have a non-blank name.

Corrective action

Give the analysis entity a short, recognizable name in its name.

Dispatch input

MetamodelEntity; once per viewpoint: true.

Kotlin declaration

com.stigway.metamodels.create.NameDefinedInAnalysisPackageRule

Kotlin implementation

com.stigway.metamodels.create.NameDefinedInAnalysisPackageRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/MetamodelPresenceRules.kt:

override fun check(container: MetamodelEntity): List<ModelProblem> = missingNameFindings(this, Viewpoint.ANALYSIS)

descriptionDefinedInAnalysisPackage

Field

Description

Name

Analysis entity has no required description

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH

Contract and evidence

Every analysis entity except Analysis and InterfacePointAnalysis shall have a non-blank description. Descriptions are not required for Analysis or InterfacePointAnalysis.

Corrective action

Describe the failure's behavior in its description.

Dispatch input

MetamodelEntity; once per viewpoint: true.

Kotlin declaration

com.stigway.metamodels.create.DescriptionDefinedInAnalysisPackageRule

Kotlin implementation

com.stigway.metamodels.create.DescriptionDefinedInAnalysisPackageRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/MetamodelPresenceRules.kt:

override fun check(container: MetamodelEntity): List<ModelProblem> = missingDescriptionFindings(this, Viewpoint.ANALYSIS)

analysisElementDefined

Field

Description

Name

Analysis has no subject element

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH

Contract and evidence

The analysis viewpoint shall reference the element it analyzes.

Corrective action

Set the analysis's element to the element whose behavior it analyses.

Dispatch input

Analysis; once per viewpoint: false.

Kotlin declaration

com.stigway.metamodels.create.analysis.AnalysisElementDefinedRule

Kotlin implementation

com.stigway.metamodels.create.analysis.AnalysisElementDefinedRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/analysis/AnalysisRules.kt:

override fun check(container: MetamodelEntity): List<ModelProblem> { val analysis = container as? Analysis ?: return emptyList() val problems = mutableListOf<ModelProblem>() if (analysis.element.name.isNullOrBlank()) { problems += ModelProblem( rule = this, severity = defaultSeverity, entityName = analysis.id, message = "${analysis.idLabel} analysis references an unnamed element.", remediation = "Set `element = ...` on analysis ${analysis.idLabel} to the named Element this " + "analysis covers. Replace placeholder/unnamed targets rather than leaving " + "the analysis detached from its element.", quickFixes = listOf( PromptSetArgumentFix(analysis.id, "element", FixValueKind.ELEMENT_REFERENCE), ), ) } return problems }

analysisQmAssessment

Field

Description

Name

Analysis omits the assessment for its QM exemption

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH

Contract and evidence

An enabled Analysis of a QM element with no interface-point analyses shall record a nonblank argument and an evaluation. Non-QM and unspecified element classifications do not qualify for this exemption.

Corrective action

Record why the QM element needs no interface-point analyses in argument and set evaluation to the supported judgment. Use FailureEvaluation.SUFFICIENT only when the assessment is sufficient.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.analysis.AnalysisQmAssessmentRule

Kotlin implementation

com.stigway.metamodels.create.analysis.AnalysisQmAssessmentRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/analysis/QmAssessmentRules.kt:

override fun check(index: ModelIndex): List<ModelProblem> = index.subjectEntities.filterIsInstance<Analysis>() .filter { it.enabled != false && it.element.asil == ASIL.QM && it.interfacePointAnalyses().isEmpty() } .mapNotNull { missingAssessment(this, index, it, it) }

interfacePointAnalysisQmAssessment

Field

Description

Name

Interface-point analysis omits the assessment for its QM exemption

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH

Contract and evidence

An empty InterfacePointAnalysis of a QM interface point shall record a nonblank argument and an evaluation instead of failure modes. Analyses with failures or member analyses retain their detailed assessment; each empty QM member analysis is checked separately. Disabled element analyses are excluded.

Corrective action

Record why the QM interface point needs no failure modes in argument and set evaluation to the supported judgment. Preserve any existing failures and assessments.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.analysis.InterfacePointAnalysisQmAssessmentRule

Kotlin implementation

com.stigway.metamodels.create.analysis.InterfacePointAnalysisQmAssessmentRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/analysis/QmAssessmentRules.kt:

override fun check(index: ModelIndex): List<ModelProblem> = index.subjectInterfaceAnalyses .filter { it.ownerAnalysis?.enabled != false && it.interfacePoint.effectiveAsil == ASIL.QM && it.allFailures().isEmpty() && !it.isDecomposed() } .mapNotNull { missingAssessment(this, index, it, it) }

interfacePointAnalysisScopeAssessment

Field

Description

Name

Interface-point analysis omits the assessment for its safety-scope exclusion

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH

Contract and evidence

A non-QM InterfacePointAnalysis with belongsToSafetyFunction=false shall record a nonblank argument and an evaluation explaining its scope. An unresolved effective ASIL does not qualify as QM. QM assessments are checked separately; disabled element analyses are excluded.

Corrective action

Explain why the interface point does not belong to the architected safety functions in argument, reference the applicable concept or assessment evidence, and set evaluation to the supported judgment. Use FailureEvaluation.SUFFICIENT when that assessment is sufficient.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.analysis.InterfacePointAnalysisScopeAssessmentRule

Kotlin implementation

com.stigway.metamodels.create.analysis.InterfacePointAnalysisScopeAssessmentRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/analysis/AnalysisScopeRules.kt:

override fun check(index: ModelIndex): List<ModelProblem> = index.subjectInterfaceAnalyses .filter { it.ownerAnalysis?.enabled != false && it.interfacePoint.effectiveAsil != ASIL.QM && it.belongsToSafetyFunction == false } .mapNotNull { missingAssessment(this, index, it, it, "an interface point outside architected safety functions") }

failureAsilDefined

Field

Description

Name

Failure has no ASIL

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH

Contract and evidence

Every Failure shall define its required asil attribute.

Corrective action

Set the asil of Failure using the applicable engineering evidence.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.analysis.FailureAsilDefinedRule

Kotlin implementation

com.stigway.metamodels.create.analysis.FailureAsilDefinedRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/analysis/AnalysisRules.kt:

class FailureAsilDefinedRule : RequiredAttributeRule<Failure>( Failure::class, Viewpoint.ANALYSIS, "asil", FixValueKind.ASIL, missing = { it.asil == null }, ) { override val name = "Failure has no ASIL" }

com.stigway.metamodels.create.RequiredAttributeRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/RequiredAttributeRule.kt:

override fun check(index: ModelIndex): List<ModelProblem> = index.subjectEntities .filter { type.java.isInstance(it) && missing(type.java.cast(it)) } .map { entity -> ModelProblem( rule = this, severity = defaultSeverity, entityName = entity.id, ownerElementId = index.ownerElement(entity)?.id, message = "${entity.idLabel} has no required $attribute value.", remediation = "Set $attribute on ${entity.idLabel} from the model's engineering evidence.", quickFixes = if (valueKind == FixValueKind.MULTIPLICITY) { Multiplicity.entries.map { SetArgumentFix( entity.id, attribute, FixExpression("Multiplicity.${it.name}") ) } } else listOf(PromptSetArgumentFix(entity.id, attribute, valueKind, listArgument = listArgument)), ) }

failureSeverityDefined

Field

Description

Name

Failure has no severity

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH

Contract and evidence

Every Failure shall define its required severity attribute.

Corrective action

Set the severity of Failure using the applicable engineering evidence.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.analysis.FailureSeverityDefinedRule

Kotlin implementation

com.stigway.metamodels.create.analysis.FailureSeverityDefinedRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/analysis/AnalysisRules.kt:

class FailureSeverityDefinedRule : RequiredAttributeRule<Failure>( Failure::class, Viewpoint.ANALYSIS, "severity", FixValueKind.SEVERITY, missing = { it.severity == null }, ) { override val name = "Failure has no severity" }

com.stigway.metamodels.create.RequiredAttributeRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/RequiredAttributeRule.kt:

override fun check(index: ModelIndex): List<ModelProblem> = index.subjectEntities .filter { type.java.isInstance(it) && missing(type.java.cast(it)) } .map { entity -> ModelProblem( rule = this, severity = defaultSeverity, entityName = entity.id, ownerElementId = index.ownerElement(entity)?.id, message = "${entity.idLabel} has no required $attribute value.", remediation = "Set $attribute on ${entity.idLabel} from the model's engineering evidence.", quickFixes = if (valueKind == FixValueKind.MULTIPLICITY) { Multiplicity.entries.map { SetArgumentFix( entity.id, attribute, FixExpression("Multiplicity.${it.name}") ) } } else listOf(PromptSetArgumentFix(entity.id, attribute, valueKind, listArgument = listArgument)), ) }

failureMultiplicityDefined

Field

Description

Name

Failure has no multiplicity

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH

Contract and evidence

Every Failure shall define its required multiplicity attribute.

Corrective action

Set the multiplicity of Failure using the applicable engineering evidence.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.analysis.FailureMultiplicityDefinedRule

Kotlin implementation

com.stigway.metamodels.create.analysis.FailureMultiplicityDefinedRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/analysis/AnalysisRules.kt:

class FailureMultiplicityDefinedRule : RequiredAttributeRule<Failure>( Failure::class, Viewpoint.ANALYSIS, "multiplicity", FixValueKind.MULTIPLICITY, missing = { it.multiplicity == null }, ) { override val name = "Failure has no multiplicity" }

com.stigway.metamodels.create.RequiredAttributeRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/RequiredAttributeRule.kt:

override fun check(index: ModelIndex): List<ModelProblem> = index.subjectEntities .filter { type.java.isInstance(it) && missing(type.java.cast(it)) } .map { entity -> ModelProblem( rule = this, severity = defaultSeverity, entityName = entity.id, ownerElementId = index.ownerElement(entity)?.id, message = "${entity.idLabel} has no required $attribute value.", remediation = "Set $attribute on ${entity.idLabel} from the model's engineering evidence.", quickFixes = if (valueKind == FixValueKind.MULTIPLICITY) { Multiplicity.entries.map { SetArgumentFix( entity.id, attribute, FixExpression("Multiplicity.${it.name}") ) } } else listOf(PromptSetArgumentFix(entity.id, attribute, valueKind, listArgument = listArgument)), ) }

failurePropagationDefined

Field

Description

Name

Failure declares no required propagation target

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH

Contract and evidence

A failure whose element has isTopLevel=false shall have at least one propagatesTo reference.

Corrective action

Add the corresponding parent failures to propagatesTo using the failure-propagation evidence. Check the element's top-level declaration if no parent effect is in scope.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.analysis.FailurePropagationDefinedRule

Kotlin implementation

com.stigway.metamodels.create.analysis.FailurePropagationDefinedRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/analysis/AnalysisRules.kt:

class FailurePropagationDefinedRule : RequiredAttributeRule<Failure>( Failure::class, Viewpoint.ANALYSIS, "propagatesTo", FixValueKind.FAILURE_REFERENCE, listArgument = true, missing = { it.ownerInterfacePointAnalysis?.ownerAnalysis?.element?.isTopLevel == false && it.propagatesTo.isEmpty() }, ) { override val name = "Failure declares no required propagation target" override val description = "A failure whose element has isTopLevel=false shall have at least one propagatesTo reference." override val remediation = "Add the corresponding parent failures to `propagatesTo` using the failure-propagation evidence. " + "Check the element's top-level declaration if no parent effect is in scope." }

com.stigway.metamodels.create.RequiredAttributeRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/RequiredAttributeRule.kt:

override fun check(index: ModelIndex): List<ModelProblem> = index.subjectEntities .filter { type.java.isInstance(it) && missing(type.java.cast(it)) } .map { entity -> ModelProblem( rule = this, severity = defaultSeverity, entityName = entity.id, ownerElementId = index.ownerElement(entity)?.id, message = "${entity.idLabel} has no required $attribute value.", remediation = "Set $attribute on ${entity.idLabel} from the model's engineering evidence.", quickFixes = if (valueKind == FixValueKind.MULTIPLICITY) { Multiplicity.entries.map { SetArgumentFix( entity.id, attribute, FixExpression("Multiplicity.${it.name}") ) } } else listOf(PromptSetArgumentFix(entity.id, attribute, valueKind, listArgument = listArgument)), ) }

failureEvaluation

Field

Description

Name

Failure lacks a sufficient or residual evaluation

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH

Contract and evidence

Every failure shall record evaluation SUFFICIENT or RESIDUAL. GAP and a missing evaluation produce HIGH on the failure, regardless of issue links, ASIL, severity, or the enclosing analysis's evaluation. Other failure completeness and consistency rules still apply.

Corrective action

Review the sufficiency of the current safety measures for this failure. Resolve an insufficient mitigation or justify a residual contribution against the applicable safety criteria; record the supported judgment in evaluation and its engineering reasoning in argument.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.analysis.FailureEvaluationRule

Kotlin implementation

com.stigway.metamodels.create.analysis.FailureEvaluationRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/analysis/FailureEvaluationRule.kt:

override fun check(index: ModelIndex): List<ModelProblem> = index.subjectFailures.mapNotNull { failure -> if (failure.evaluation == FailureEvaluation.SUFFICIENT || failure.evaluation == FailureEvaluation.RESIDUAL) { return@mapNotNull null } ModelProblem( rule = this, severity = defaultSeverity, entityName = failure.id, ownerElementId = index.ownerElement(failure)?.id, message = if (failure.evaluation == null) { "${failure.idLabel} has no recorded evaluation of mitigation sufficiency; expected SUFFICIENT or RESIDUAL." } else { "${failure.idLabel} has evaluation ${failure.evaluation}; the sufficiency of measures or justification for a residual contribution remains unresolved." }, ) }

failureArgument

Field

Description

Name

Failure records a positive evaluation without an argument

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH

Contract and evidence

A failure evaluated SUFFICIENT or RESIDUAL shall record a nonblank engineering argument. This applies to every positive conclusion, regardless of severity, ASIL, or issue links.

Corrective action

Explain why the measures sufficiently address this failure, or why its residual contribution satisfies the applicable criteria. Record the assumptions and supporting evidence in argument and sources.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.analysis.FailureArgumentRule

Kotlin implementation

com.stigway.metamodels.create.analysis.FailureArgumentRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/analysis/FailureEvaluationRule.kt:

/** Positive conclusions require their own engineering justification, including explicitly QM failures. */ class FailureArgumentRule : RequiredAttributeRule<Failure>( Failure::class, Viewpoint.ANALYSIS, "argument", FixValueKind.MULTILINE_STRING, missing = { (it.evaluation == FailureEvaluation.SUFFICIENT || it.evaluation == FailureEvaluation.RESIDUAL) && it.argument.isNullOrBlank() }, ) { override val name = "Failure records a positive evaluation without an argument" override val description = "A failure evaluated SUFFICIENT or RESIDUAL shall record a nonblank engineering argument. " + "This applies to every positive conclusion, regardless of severity, ASIL, or issue links." override val remediation = "Explain why the measures sufficiently address this failure, or why its residual contribution satisfies " + "the applicable criteria. Record the assumptions and supporting evidence in `argument` and `sources`." }

com.stigway.metamodels.create.RequiredAttributeRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/RequiredAttributeRule.kt:

override fun check(index: ModelIndex): List<ModelProblem> = index.subjectEntities .filter { type.java.isInstance(it) && missing(type.java.cast(it)) } .map { entity -> ModelProblem( rule = this, severity = defaultSeverity, entityName = entity.id, ownerElementId = index.ownerElement(entity)?.id, message = "${entity.idLabel} has no required $attribute value.", remediation = "Set $attribute on ${entity.idLabel} from the model's engineering evidence.", quickFixes = if (valueKind == FixValueKind.MULTIPLICITY) { Multiplicity.entries.map { SetArgumentFix( entity.id, attribute, FixExpression("Multiplicity.${it.name}") ) } } else listOf(PromptSetArgumentFix(entity.id, attribute, valueKind, listArgument = listArgument)), ) }

failureSeverityValue

Field

Description

Name

Failure has an invalid severity value

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH

Contract and evidence

Failure.severity shall be finite and within 0.01 (inclusive) of an integer from 0 through 10. Severity.value retains the supplied Float; this check does not round or change it. Missing severity is checked by failureSeverityDefined.

Corrective action

Set severity to the justified integer class from Severity.S0 through Severity.S10. Confirm the intended class before replacing an invalid numeric value.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.analysis.FailureSeverityValueRule

Kotlin implementation

com.stigway.metamodels.create.analysis.FailureSeverityValueRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/analysis/FailureSeverityValueRule.kt:

override fun check(index: ModelIndex): List<ModelProblem> = index.subjectFailures.mapNotNull { failure -> val severity = failure.severity?.value ?: return@mapNotNull null if (severity.failureSeverityClass != null) return@mapNotNull null ModelProblem( rule = this, severity = defaultSeverity, entityName = failure.id, ownerElementId = index.ownerElement(failure)?.id, message = "${failure.idLabel} has invalid severity $severity; expected a finite value within 0.01 " + "of an integer from 0 through 10.", remediation = "Set severity on ${failure.idLabel} to the engineering-justified integer class " + "from Severity.S0 through Severity.S10, or use Severity(10.0f). Do not round an invalid value " + "without confirming the intended class.", quickFixes = listOf(PromptSetArgumentFix(failure.id, "severity", FixValueKind.SEVERITY)), ) }

interfacePointS10Failure

Field

Description

Name

Interface-point analysis contains no required S10 failure

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH

Contract and evidence

An interface point with ASIL > QM shall have at least one failure with severity ≥ S10 (10.0). QM interface points, required/subscribed data and analyses with belongsToSafetyFunction=false are exempt. Methods are checked in both required and provided directions; member uses inherit their port's direction. For an analysis decomposed into member analyses without direct failures, check each member analysis.

Corrective action

Describe the safety-goal-violating failure in the interface-point analysis and assign its justified Severity.S10 classification. If the interface point was incorrectly classified as safety-relevant, resolve its ASIL against the safety evidence.

Dispatch input

Analysis; once per viewpoint: false.

Kotlin declaration

com.stigway.metamodels.create.analysis.InterfacePointS10FailureRule

Kotlin implementation

com.stigway.metamodels.create.analysis.InterfacePointS10FailureRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/analysis/AnalysisRules.kt:

override fun check(container: MetamodelEntity): List<ModelProblem> { val problems = mutableListOf<ModelProblem>() for (ipa in container.allInterfacePointAnalyses()) { if (ipa.isDecomposed() || !ipa.requiresDetailedFunctionalAnalysis()) continue val interfacePointAsil = ipa.interfacePoint.effectiveAsil ?: continue val failures = ipa.allFailures() val hasS10 = failures.any { (it.severity?.value ?: 0f) >= 10f } if (!hasS10) { problems += ModelProblem( rule = this, severity = defaultSeverity, entityName = ipa.id, message = "Interface point ${ipa.interfacePoint.idLabel} has ASIL ${interfacePointAsil.name} (> QM), " + "but analysis ${ipa.idLabel} has no failure with severity ≥ S10.", remediation = "Add at least one safety-relevant Failure under interface-point analysis " + "${ipa.idLabel} with `severity = Severity.S10`. " + "Use the referenced interface point's ASIL ${interfacePointAsil.name} when classifying the failure.", remediationSummary = "Add a safety-relevant failure with `severity = Severity.S10`, using the interface point's ASIL ${interfacePointAsil.name}.", quickFixes = listOf( CreateChildEntityFix( ipa.id, "Failure", "Failure(severity = Severity.S10, asil = ASIL.${interfacePointAsil.name})" ), ), ) } } return problems }

interfacePointAnalysisCoverage

Field

Description

Name

Analysis omits an interface point

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH

Contract and evidence

Every interface point whose effective ASIL is not QM, including unresolved ASIL, and that is reachable through a ProvidedPort or Publisher, shall have an interface-point analysis on itself, an ancestor or a descendant in the same element's interface tree. Methods also require coverage through RequiredPort. Data reachable only through RequiredPort or Subscriber usage is outside this check, since the receiving element does not own that signal's failure modes. Member uses inherit port direction. Sibling branches and other elements do not supply coverage. QM elements and explicitly disabled element analyses are outside this check. Coverage is collective across enabled analyses. A missing analysis is reported on the single enabled Analysis, or on the element when there is no single Analysis container.

Corrective action

Add an InterfacePointAnalysis for this point, an ancestor or a descendant in the owning element's interface tree, then document the applicable failures. Required/subscribed data needs no analysis here; required and provided methods both need coverage.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.analysis.InterfacePointAnalysisCoverageRule

Kotlin implementation

com.stigway.metamodels.create.analysis.InterfacePointAnalysisCoverageRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/analysis/InterfacePointAnalysisCoverageRule.kt:

override fun check(index: ModelIndex): List<ModelProblem> = buildList { val points = index.entities.filterIsInstance<InterfacePoint>() for (element in index.subjectElements) { if (element.asil == ASIL.QM) continue val members = points.filter { index.interfaceBelongsTo(it, element) } if (members.isEmpty()) continue val ancestors = members.associateWith { index.interfaceAncestors(it, element) } val required = members.filter { it.effectiveAsil != ASIL.QM && !index.isRequiredDataOnly(it, element) } if (required.isEmpty()) continue index.requireCompleteContent(listOf(element)) val analyses = index.analysesOf(element) val enabled = analyses.filter { it.enabled != false } if (analyses.isNotEmpty() && enabled.isEmpty()) continue val target = enabled.singleOrNull() ?: element as MetamodelEntity val analysedPoints = index.interfaceAnalyses.filter { it.ownerAnalysis in enabled && index.interfaceBelongsTo(it.interfacePoint, element) }.map { it.interfacePoint }.distinct() for (point in required) { if (analysedPoints.any { it in ancestors.getValue(point) || point in ancestors.getValue(it) }) continue // A selective port member-use is the actionable, most specific coverage point; its own raw // service-interface-level declaration is only a generic restatement of the same gap. Report once. if (point !is PortMemberUse<*>) { val aliases = required.filter { it is PortMemberUse<*> && point in ancestors.getValue(it) } if (aliases.size == 1) continue } add( ModelProblem( this@InterfacePointAnalysisCoverageRule, defaultSeverity, "${target.idLabel} omits an interface-point analysis of ${point.idLabel}, " + "an ancestor or a descendant in the interface tree of ${element.idLabel}.", entityName = target.id, ownerElementId = element.id, subjectId = "${point.id}#analysisCoverage:${element.id}", relatedEntityIds = listOf(point.id), ) ) } } }

failureNameSeverityMatch

Field

Description

Name

Failure name contradicts its severity

Contributor unknown

false

Default severity

MODERATE

Possible finding severities

MODERATE

Contract and evidence

If a failure name ends with _S<number> (e.g., _S8, _S10), that number shall match severity.

Corrective action

Align the _S&lt;number&gt; suffix in name with the justified severity value. Correct the name when the severity is already supported by the analysis.

Dispatch input

Analysis; once per viewpoint: false.

Kotlin declaration

com.stigway.metamodels.create.analysis.FailureNameSeverityMatchRule

Kotlin implementation

com.stigway.metamodels.create.analysis.FailureNameSeverityMatchRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/analysis/AnalysisRules.kt:

override fun check(container: MetamodelEntity): List<ModelProblem> { val problems = mutableListOf<ModelProblem>() val severityPattern = Regex("_S(\\d+)$") for (ipa in container.allInterfacePointAnalyses()) { for (failure in ipa.allFailures()) { val name = failure.name ?: continue val matchResult = severityPattern.find(name) if (matchResult != null) { val nameSeverityNum = matchResult.groupValues[1].toFloatOrNull() ?: continue val fieldSeverity = failure.severity?.value ?: continue if (nameSeverityNum != fieldSeverity) { val quickFixes = buildList { if (nameSeverityNum.failureSeverityClass != null) { add(SetArgumentFix(failure.id, "severity", severityExpr(nameSeverityNum))) } val fieldClass = fieldSeverity.failureSeverityClass // Renaming alone cannot make a fractional field exactly match an integer suffix. if (fieldClass != null && fieldSeverity == fieldClass.toFloat()) { add( RewriteStringArgumentFix( failure.id, "name", name.replaceRange(matchResult.range, "_S$fieldClass") ) ) } if (isEmpty()) { add(PromptSetArgumentFix(failure.id, "severity", FixValueKind.SEVERITY)) } } problems += ModelProblem( rule = this, severity = defaultSeverity, entityName = failure.id, message = "${failure.idLabel} has name '$name' with suffix ${matchResult.value} but severity is $fieldSeverity.", remediation = "Confirm the intended severity class from 0 through 10 for ${failure.idLabel}; " + "align Severity.value and the name's _S<number> suffix without " + "rounding an invalid value or changing the rest of the name.", quickFixes = quickFixes, ) } } } } return problems }

failureDescriptionElement

Field

Description

Name

Failure description omits its element name at the start

Contributor unknown

false

Default severity

MODERATE

Possible finding severities

MODERATE

Contract and evidence

A failure's description shall begin with the complete name of the element analysed by its owning Analysis.

Corrective action

Start the failure's description with the complete name of the element analysed by its owning Analysis, then describe the failure behavior.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.analysis.FailureDescriptionElementRule

Kotlin implementation

com.stigway.metamodels.create.analysis.FailureDescriptionElementRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/analysis/AnalysisBoundaryRules.kt:

override fun check(index: ModelIndex): List<ModelProblem> = index.subjectFailures.mapNotNull { failure -> val element = index.ownerElement(failure) ?: return@mapNotNull null val name = element.name?.takeIf { it.isNotBlank() } ?: return@mapNotNull null val text = failure.description?.takeIf { it.isNotBlank() } ?: return@mapNotNull null if (Regex("^${completeName(name)}").containsMatchIn(normalized(text))) return@mapNotNull null ModelProblem( this, defaultSeverity, "${failure.idLabel} description shall start with the name '$name' of ${element.idLabel}.", entityName = failure.id, ownerElementId = element.id ) }

failureDescriptionInterface

Field

Description

Name

Failure description omits its interface name after the element name

Contributor unknown

false

Default severity

MODERATE

Possible finding severities

MODERATE

Contract and evidence

A failure's description shall mention the complete name of its owning InterfacePointAnalysis's analysed interface point after its initial element name.

Corrective action

After the initial element name, include the complete name of the analysed interface point in the failure's description.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.analysis.FailureDescriptionInterfaceRule

Kotlin implementation

com.stigway.metamodels.create.analysis.FailureDescriptionInterfaceRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/analysis/AnalysisBoundaryRules.kt:

override fun check(index: ModelIndex): List<ModelProblem> = index.subjectFailures.mapNotNull { failure -> val element = index.ownerElement(failure) ?: return@mapNotNull null val elementName = element.name?.takeIf { it.isNotBlank() } ?: return@mapNotNull null val interfacePoint = failure.ownerInterfacePointAnalysis?.interfacePoint ?: return@mapNotNull null val name = interfacePoint.name?.takeIf { it.isNotBlank() } ?: return@mapNotNull null val text = failure.description?.takeIf { it.isNotBlank() }?.let(::normalized) ?: return@mapNotNull null val prefix = Regex("^${completeName(elementName)}").find(text) ?: return@mapNotNull null if (Regex(completeName(name)).containsMatchIn(text.substring(prefix.range.last + 1))) return@mapNotNull null ModelProblem( this, defaultSeverity, "${failure.idLabel} description shall mention the name '$name' of ${interfacePoint.idLabel} " + "after the name '$elementName' of ${element.idLabel}.", entityName = failure.id, ownerElementId = element.id ) }

failureQmSeverity

Field

Description

Name

QM failure reaches S10 severity

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH

Contract and evidence

A failure with ASIL = QM shall have severity < S10 (10.0), otherwise it shall be safety-relevant.

Corrective action

Reassess the failure's effect and safety classification. Assign the justified safety-relevant asil for an S10 effect, or correct an overstated severity when the effect is below S10.

Dispatch input

Analysis; once per viewpoint: false.

Kotlin declaration

com.stigway.metamodels.create.analysis.FailureQmSeverityRule

Kotlin implementation

com.stigway.metamodels.create.analysis.FailureQmSeverityRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/analysis/AnalysisRules.kt:

override fun check(container: MetamodelEntity): List<ModelProblem> { val problems = mutableListOf<ModelProblem>() for (ipa in container.allInterfacePointAnalyses()) { for (failure in ipa.allFailures()) { if (failure.asil != ASIL.QM) continue val sev = failure.severity?.value ?: continue if (sev >= 10f) { problems += ModelProblem( rule = this, severity = defaultSeverity, entityName = failure.id, message = "${failure.idLabel} has ASIL QM but severity $sev ≥ S10 (should be safety-relevant).", remediation = "Set failure ${failure.idLabel} to a safety-relevant ASIL (`ASIL.A` or " + "higher as appropriate), or lower `severity` below 10 only if the " + "S10 severity classification is incorrect.", quickFixes = listOf( PromptSetArgumentFix(failure.id, "asil", FixValueKind.ASIL), SetArgumentFix(failure.id, "severity", FixExpression("Severity.S9")), ), ) } } } return problems }

failureS10SafetyMeasures

Field

Description

Name

Failure lacks a safety measure or valid independent failure

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH

Contract and evidence

A failure with severity ≥ S10 (10.0), missing severity, ASIL above QM, or missing ASIL shall have at least one safety measure or valid independent failure on a separate element branch. Only a failure explicitly classified QM with severity below S10 is exempt.

Corrective action

Reference an applicable safety measure in mitigatedBy or an independent failure on a separate element branch in independentFailures, using the agreed safety concept.

Dispatch input

Analysis; once per viewpoint: false.

Kotlin declaration

com.stigway.metamodels.create.analysis.FailureS10SafetyMeasuresRule

Kotlin implementation

com.stigway.metamodels.create.analysis.FailureS10SafetyMeasuresRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/analysis/AnalysisRules.kt:

override fun check(container: MetamodelEntity): List<ModelProblem> { val problems = mutableListOf<ModelProblem>() for (ipa in container.allInterfacePointAnalyses()) { for (failure in ipa.allFailures()) { val sev = failure.severity?.value if (sev != null && sev < 10f && failure.asil == ASIL.QM) continue val index = ModelIndex.current() if (failure.mitigatedBy.isEmpty() && failure.independentFailures.none { index.independentElements(failure, it) }) { problems += ModelProblem( rule = this, severity = defaultSeverity, entityName = failure.id, message = "${failure.idLabel} has severity ${sev ?: "unspecified"} and ASIL " + "${failure.asil?.name ?: "unspecified"}, but no safety measure or valid independent failure.", remediation = "Reference a safety measure in `mitigatedBy` or a valid failure on a separate element branch " + "in `independentFailures` for ${failure.idLabel}.", quickFixes = listOf( PromptSetArgumentFix( failure.id, "mitigatedBy", FixValueKind.SAFETY_MEASURE_REFERENCE, listArgument = true ), PromptSetArgumentFix( failure.id, "independentFailures", FixValueKind.FAILURE_REFERENCE, listArgument = true ), ), ) } } } return problems }

failureTopLevelNoPropagation

Field

Description

Name

Top-level failure declares propagation targets

Contributor unknown

false

Default severity

MODERATE

Possible finding severities

MODERATE

Contract and evidence

An entity on an element with isTopLevel=true should have no propagatesTo references.

Corrective action

Check the element's isTopLevel flag against the agreed model scope. If the flag is correct, remove the references in propagatesTo; otherwise correct the flag to match the intended hierarchy.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.analysis.FailureTopLevelNoPropagationRule

Kotlin implementation

com.stigway.metamodels.create.analysis.FailureTopLevelNoPropagationRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/analysis/AnalysisRules.kt:

class FailureTopLevelNoPropagationRule : BoundaryLinksRule<Failure>( Failure::class, Viewpoint.ANALYSIS, "propagatesTo", "isTopLevel", { it.ownerInterfacePointAnalysis?.ownerAnalysis?.element?.isTopLevel == true && it.propagatesTo.isNotEmpty() }, ) { override val name = "Top-level failure declares propagation targets" }

com.stigway.metamodels.create.BoundaryLinksRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/BoundaryRules.kt:

override fun check(index: ModelIndex): List<ModelProblem> = index.subjectEntities .filter { type.java.isInstance(it) && violates(type.java.cast(it)) } .map { entity -> ModelProblem( this, defaultSeverity, "${entity.idLabel} has $attribute references although its element has $boundary=true.", entityName = entity.id, ownerElementId = index.ownerElement(entity)?.id, remediation = "Review the element's $boundary declaration and the authored $attribute references." ) }

forbiddenWordsInAnalysis

Field

Description

Name

Analysis entity contains forbidden wording

Contributor unknown

false

Default severity

MODERATE

Possible finding severities

MODERATE

Contract and evidence

String attributes in the analysis viewpoint shall not contain the configured forbidden words. The default list only rejects explicit unfinished-work markers: tbd, tbc, todo, fixme. Narrative failure descriptions and assessment arguments may use uncertainty and qualitative wording. Check constructor attributes, including names, descriptions, arguments, comments, verification criteria, collections, and nested metadata. Match whole words/phrases without regard to case. Referenced model entities are checked in their own viewpoint and module scope. KDoc, source comments, generated identities, and enum names are not string attributes.

Corrective action

Replace the reported wording in the named attribute with precise, testable conditions and justified values. Obtain missing engineering decisions before completing the statement.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.ForbiddenWordsInAnalysisRule

Kotlin implementation

com.stigway.metamodels.create.ForbiddenWordsInAnalysisRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/ForbiddenWordsRules.kt:

class ForbiddenWordsInAnalysisRule : ForbiddenWordsInViewpointRule(Viewpoint.ANALYSIS) { override val name = "Analysis entity contains forbidden wording" }

com.stigway.metamodels.create.ForbiddenWordsInViewpointRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/ForbiddenWordsRules.kt:

final override fun check(index: ModelIndex): List<ModelProblem> = buildList { for (entity in index.subjectEntities.filter { index.viewpoint(it) == viewpoint }.sortedBy { it.id }) { for ((attribute, text) in modelStringAttributes(entity)) { val found = findForbiddenPhrases(text, phrases) if (found.isEmpty()) continue add( ModelProblem( rule = this@ForbiddenWordsInViewpointRule, severity = defaultSeverity, entityName = entity.id, subjectId = "${entity.id}:$attribute", message = "${entity.idLabel} contains forbidden words in `$attribute`: ${found.joinToString(", ")}.", remediation = "Replace the reported wording in `$attribute` on ${entity.idLabel} with precise, testable " + "conditions: ${found.joinToString(", ")}. Resolve missing engineering decisions " + "before using this text as released evidence.", quickFixes = if ('.' !in attribute && '[' !in attribute) { listOf(RewriteStringArgumentFix(entity.id, attribute, text)) } else emptyList(), ) ) } } }

interfacePointAnalysisUsedInNotEmpty

Field

Description

Name

Interface-point analysis declares no required parent dependency

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH

Contract and evidence

An interface-point analysis whose element has isTopLevel=false shall have at least one usedIn reference. QM interface points, required/subscribed data and analyses with belongsToSafetyFunction=false are exempt. Methods are checked in both required and provided directions; member uses inherit their port's direction. An analysis decomposed into member analyses without direct failures delegates this check to its members.

Corrective action

Add the parent interface points that use this analysed interface point to usedIn. Check the element's top-level declaration if no parent contribution is in scope.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.analysis.InterfacePointAnalysisUsedInNotEmptyRule

Kotlin implementation

com.stigway.metamodels.create.analysis.InterfacePointAnalysisUsedInNotEmptyRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/analysis/AnalysisRules.kt:

class InterfacePointAnalysisUsedInNotEmptyRule : RequiredAttributeRule<InterfacePointAnalysis>( InterfacePointAnalysis::class, Viewpoint.ANALYSIS, "usedIn", FixValueKind.INTERFACE_POINT_REFERENCE, listArgument = true, missing = { it.requiresDetailedFunctionalAnalysis() && it.ownerAnalysis?.element?.isTopLevel == false && it.usedIn.isEmpty() && !it.isDecomposed() }, ) { override val name = "Interface-point analysis declares no required parent dependency" override val description = "An interface-point analysis whose element has isTopLevel=false shall have at least one usedIn reference. " + "QM interface points, required/subscribed data and analyses with belongsToSafetyFunction=false are exempt. " + "Methods are checked in both required and provided directions; member uses inherit their port's direction. " + "An analysis decomposed into member analyses without direct failures delegates this check to its members." override val remediation = "Add the parent interface points that use this analysed interface point to `usedIn`. " + "Check the element's top-level declaration if no parent contribution is in scope." }

com.stigway.metamodels.create.RequiredAttributeRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/RequiredAttributeRule.kt:

override fun check(index: ModelIndex): List<ModelProblem> = index.subjectEntities .filter { type.java.isInstance(it) && missing(type.java.cast(it)) } .map { entity -> ModelProblem( rule = this, severity = defaultSeverity, entityName = entity.id, ownerElementId = index.ownerElement(entity)?.id, message = "${entity.idLabel} has no required $attribute value.", remediation = "Set $attribute on ${entity.idLabel} from the model's engineering evidence.", quickFixes = if (valueKind == FixValueKind.MULTIPLICITY) { Multiplicity.entries.map { SetArgumentFix( entity.id, attribute, FixExpression("Multiplicity.${it.name}") ) } } else listOf(PromptSetArgumentFix(entity.id, attribute, valueKind, listArgument = listArgument)), ) }

interfacePointAnalysisTopLevelNoUsedIn

Field

Description

Name

Top-level interface-point analysis declares parent dependencies

Contributor unknown

false

Default severity

MODERATE

Possible finding severities

MODERATE

Contract and evidence

An entity on an element with isTopLevel=true should have no usedIn references.

Corrective action

Check the element's isTopLevel flag against the agreed model scope. If the flag is correct, remove the references in usedIn; otherwise correct the flag to match the intended hierarchy.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.analysis.InterfacePointAnalysisTopLevelNoUsedInRule

Kotlin implementation

com.stigway.metamodels.create.analysis.InterfacePointAnalysisTopLevelNoUsedInRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/analysis/AnalysisRules.kt:

class InterfacePointAnalysisTopLevelNoUsedInRule : BoundaryLinksRule<InterfacePointAnalysis>( InterfacePointAnalysis::class, Viewpoint.ANALYSIS, "usedIn", "isTopLevel", { it.ownerAnalysis?.element?.isTopLevel == true && it.usedIn.isNotEmpty() }, ) { override val name = "Top-level interface-point analysis declares parent dependencies" }

com.stigway.metamodels.create.BoundaryLinksRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/BoundaryRules.kt:

override fun check(index: ModelIndex): List<ModelProblem> = index.subjectEntities .filter { type.java.isInstance(it) && violates(type.java.cast(it)) } .map { entity -> ModelProblem( this, defaultSeverity, "${entity.idLabel} has $attribute references although its element has $boundary=true.", entityName = entity.id, ownerElementId = index.ownerElement(entity)?.id, remediation = "Review the element's $boundary declaration and the authored $attribute references." ) }

interfacePointAnalysisUsedInParentElement

Field

Description

Name

Interface-point analysis links outside its eligible analysis parent

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH

Contract and evidence

Each usedIn entry shall belong to the element's analysis parent: its direct parent, or its grandparent when the direct parent's Analysis is absent or disabled. The grandparent shall have an enabled Analysis; only one level may be bypassed.

Corrective action

Replace an invalid usedIn entry with an interface point of the direct analysis parent. Use a grandparent only when the direct parent's Analysis is absent or disabled and the grandparent has an enabled Analysis.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.analysis.InterfacePointAnalysisUsedInParentElementRule

Kotlin implementation

com.stigway.metamodels.create.analysis.InterfacePointAnalysisUsedInParentElementRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/analysis/AnalysisRules.kt:

override fun check(index: ModelIndex): List<ModelProblem> = index.subjectInterfaceAnalyses.flatMap { analysis -> val element = analysis.ownerAnalysis?.element ?: return@flatMap emptyList() if (analysis.ownerAnalysis?.enabled == false || analysis.usedIn.isEmpty()) { return@flatMap emptyList() } val parent = index.analysisParentOf(element) analysis.usedIn.mapNotNull { target -> val belongsToParent = parent != null && index.interfaceBelongsTo(target, parent) if (belongsToParent) { index.requireCompleteContent(listOf(parent)) if (index.hasEnabledAnalysis(parent)) return@mapNotNull null } ModelProblem( this, defaultSeverity, if (belongsToParent) "${analysis.idLabel}.usedIn targets ${target.idLabel}, but its grandparent has no enabled Analysis; a second bypass is not allowed." else "${analysis.idLabel}.usedIn contains ${target.idLabel}, which is not an interface point of its analysis parent (allowing one absent or disabled Analysis level).", entityName = analysis.id, ownerElementId = element.id, relatedEntityIds = listOf(target.id), quickFixes = listOf(RemoveListItemFix(analysis.id, "usedIn", interfacePointExpr(target))) ) } }

interfacePointAsilUsedIn

Field

Description

Name

Interface-point analysis has no parent dependency with sufficient ASIL

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH INFO

Contract and evidence

At least one usedIn parent interface point shall have ASIL greater than or equal to the analyzed interface point (HIGH on the source interface-point analysis). A target above all its classified contributors receives INFO.

Corrective action

Check usedIn and the linked parent interface points' ASILs. Link the actual parent contribution and align its classification with the analysed interface point's safety obligation.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.analysis.InterfacePointAsilUsedInRule

Kotlin implementation

com.stigway.metamodels.create.analysis.InterfacePointAsilUsedInRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/analysis/AnalysisRules.kt:

override fun check(index: ModelIndex): List<ModelProblem> { val problems = mutableListOf<ModelProblem>() val analyses = index.interfaceAnalyses for (ipa in analyses) { if (!index.isSubject(ipa)) continue val interfacePointAsil = ipa.interfacePoint.effectiveAsil ?: continue if (ipa.usedIn.isEmpty()) continue val parentAsils = ipa.usedIn.mapNotNull { it.effectiveAsil } if (parentAsils.isEmpty()) continue if (parentAsils.none { it >= interfacePointAsil }) { problems += ModelProblem( rule = this, severity = defaultSeverity, entityName = ipa.id, subjectId = "${ipa.id}#usedIn", relatedEntityIds = listOf(ipa.interfacePoint.id) + ipa.usedIn.map { it.id }, message = "Interface point ${ipa.interfacePoint.idLabel} has ASIL ${interfacePointAsil.name}, " + "but analysis ${ipa.idLabel} has no usedIn parent with ASIL ≥ ${interfacePointAsil.name}.", remediation = "Review the `usedIn` references on ${ipa.idLabel} and the interface-point classifications. " + "At least one actual parent interface point must have ASIL ≥ ${interfacePointAsil.name}. " + "Remove or replace incorrect references. Current usedIn targets: " + interfacePointAsilList(ipa.usedIn) + ".", remediationSummary = "Correct `usedIn` so an actual parent interface point supports ASIL ${interfacePointAsil.name}, or review the source classification against the safety evidence.", quickFixes = ipa.usedIn.map { RemoveListItemFix(ipa.id, "usedIn", interfacePointExpr(it)) }, ) } } val incoming = analyses.flatMap { source -> source.usedIn.map { it to source } } .groupBy({ it.first }, { it.second }) for ((point, sources) in incoming) { if (point !is MetamodelEntity || sources.any { it.interfacePoint !is MetamodelEntity }) continue classificationDifference( this, index, ClassificationValue(point, point.effectiveAsil), sources.map { ClassificationValue( it.interfacePoint as MetamodelEntity, it.interfacePoint.effectiveAsil ) }, "ASIL", "usedIn contributors", ) { index.elements.filter { index.interfaceBelongsTo(point, it) } .flatMap(index::classificationContributionElements) }?.let(problems::add) } return problems }

failureAsilBound

Field

Description

Name

Failure exceeds its interface point's ASIL

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH INFO

Contract and evidence

Each failure's ASIL shall not exceed its interface point's ASIL (HIGH on the failure). If every failure is classified and their maximum is lower, report INFO on the interface point.

Corrective action

Review the failure classification against its owning analysis's referenced interface point.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.analysis.FailureAsilBoundRule

Kotlin implementation

com.stigway.metamodels.create.analysis.FailureAsilBoundRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/analysis/AnalysisRules.kt:

override fun check(index: ModelIndex): List<ModelProblem> = buildList { val byPoint = index.failures.filter { it.ownerInterfacePointAnalysis != null } .groupBy { it.ownerInterfacePointAnalysis!!.interfacePoint } for ((point, failures) in byPoint) { val limit = point.effectiveAsil ?: continue for (failure in failures.filter(index::isSubject)) { val value = failure.asil ?: continue if (value <= limit) continue add( ModelProblem( this@FailureAsilBoundRule, defaultSeverity, "${failure.idLabel} has ASIL ${value.name}, which exceeds interface point " + "${point.idLabel} ASIL ${limit.name} in analysis ${failure.ownerInterfacePointAnalysis!!.idLabel}.", entityName = failure.id, remediation = "Review failure ${failure.idLabel} against the referenced interface point's " + "ASIL ${limit.name} and select a classification no higher than that bound.", remediationSummary = "Review the failure's ASIL and select a classification no higher than the interface point's ASIL ${limit.name}.", quickFixes = listOf(SetArgumentFix(failure.id, "asil", FixExpression("ASIL.${limit.name}"))), ) ) } classificationDifference( this@FailureAsilBoundRule, index, ClassificationValue(point as? MetamodelEntity ?: continue, limit), failures.map { ClassificationValue(it, it.asil) }, "ASIL", "failures", ) { index.elements.filter { index.interfaceBelongsTo(point, it) } + failures.mapNotNull(index::ownerElement) }?.let(::add) } }

failureAsilPropagation

Field

Description

Name

Failure exceeds every propagation target's ASIL

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH INFO

Contract and evidence

At least one propagation target shall have ASIL at least as high as the source failure (HIGH on the source). A target above all its classified incoming failures receives INFO.

Corrective action

Check the failures in propagatesTo and their ASILs against the source failure's safety obligation. Correct an incorrect target reference or classification using the propagation evidence.

Dispatch input

Analysis; once per viewpoint: false.

Kotlin declaration

com.stigway.metamodels.create.analysis.FailureAsilPropagationRule

Kotlin implementation

com.stigway.metamodels.create.analysis.FailureAsilPropagationRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/analysis/AnalysisRules.kt:

override fun check(container: MetamodelEntity): List<ModelProblem> { val problems = mutableListOf<ModelProblem>() for (ipa in container.allInterfacePointAnalyses()) { for (failure in ipa.allFailures()) { val index = ModelIndex.current() classificationDifference( this, index, ClassificationValue(failure, failure.asil), index.incomingFailures(failure).map { ClassificationValue(it, it.asil) }, "ASIL", "incoming failures", ) { index.ownerElement(failure)?.let(index::classificationContributionElements).orEmpty() }?.let(problems::add) val failAsil = failure.asil ?: continue if (failure.propagatesTo.isEmpty()) continue val targetAsils = failure.propagatesTo.mapNotNull { it.asil } if (targetAsils.isEmpty()) continue if (targetAsils.none { it >= failAsil }) { val maxTargetAsil = targetAsils.max() problems += ModelProblem( rule = this, severity = defaultSeverity, entityName = failure.id, message = "${failure.idLabel} has ASIL ${failAsil.name} but no propagatesTo target has ASIL ≥ ${failAsil.name}.", remediation = "Set failure ${failure.idLabel} to `asil = ASIL.${maxTargetAsil.name}`. " + "This is the highest ASIL available from its propagation targets. If the " + "propagation relation is wrong, remove or replace the `propagatesTo` " + "references on this failure. Current targets: " + failureAsilList(failure.propagatesTo) + ".", remediationSummary = "Set `asil = ASIL.${maxTargetAsil.name}` to match the highest propagation-target ASIL, or correct an incorrect `propagatesTo` relation.", quickFixes = listOf(SetArgumentFix(failure.id, "asil", FixExpression("ASIL.${maxTargetAsil.name}"))) + failure.propagatesTo.map { RemoveListItemFix(failure.id, "propagatesTo", failureExpr(it)) }, ) } } } return problems }

failurePropagationUsedInConsistency

Field

Description

Name

Failure propagates outside its declared interface dependencies

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH

Contract and evidence

A failure may only propagate to failures whose owner InterfacePointAnalysis analyses an InterfacePoint listed in the source InterfacePointAnalysis's usedIn.

Corrective action

Align the source analysis's usedIn interface points with the analyses owning its propagatesTo targets. Add the missing parent interface-point link or correct the failure target to match the actual propagation.

Dispatch input

Analysis; once per viewpoint: false.

Kotlin declaration

com.stigway.metamodels.create.analysis.FailurePropagationUsedInConsistencyRule

Kotlin implementation

com.stigway.metamodels.create.analysis.FailurePropagationUsedInConsistencyRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/analysis/AnalysisRules.kt:

override fun check(container: MetamodelEntity): List<ModelProblem> { ModelIndex.current() val problems = mutableListOf<ModelProblem>() for (interfacePointAnalysis in container.allInterfacePointAnalyses()) { val allowedParents = interfacePointAnalysis.usedIn.toSet() val allowedParentLabel = allowedParents.joinToString(", ") { it.idLabel }.ifEmpty { "(none)" } val sourceIpaLabel = interfacePointAnalysis.idLabel val sourceIpLabel = interfacePointAnalysis.interfacePoint.idLabel for (failure in interfacePointAnalysis.allFailures()) { if (failure.propagatesTo.isEmpty()) continue for (target in failure.propagatesTo) { val targetIpa = target.ownerInterfacePointAnalysis val targetIp = targetIpa?.interfacePoint if (targetIp != null && targetIp in allowedParents) continue val sourceFailureLabel = failure.idLabel val targetFailureLabel = target.idLabel val targetIpaLabel = targetIpa?.idLabel ?: "(unidentified InterfacePointAnalysis — owner not wired)" val targetIpLabel = targetIp?.idLabel ?: "(unidentified InterfacePoint)" problems += ModelProblem( rule = this, severity = defaultSeverity, entityName = failure.id, message = "Failure $sourceFailureLabel (in InterfacePointAnalysis $sourceIpaLabel " + "analysing InterfacePoint $sourceIpLabel) propagates to $targetFailureLabel " + "(in InterfacePointAnalysis $targetIpaLabel analysing InterfacePoint $targetIpLabel), " + "but $sourceIpaLabel.usedIn lists: $allowedParentLabel — " + "a failure may only propagate to failures of InterfacePointAnalysis instances " + "whose InterfacePoint is listed in the source IPA's usedIn.", remediation = "Update source IPA $sourceIpaLabel so its `usedIn` includes " + "$targetIpLabel, or remove/replace the `propagatesTo` entry " + "$targetFailureLabel on failure $sourceFailureLabel. Do not " + "change the target failure owner only to satisfy this source relation.", quickFixes = listOfNotNull( targetIp?.let { AddListItemFix(interfacePointAnalysis.id, "usedIn", interfacePointExpr(it)) }, RemoveListItemFix(failure.id, "propagatesTo", failureExpr(target)), ), ) } } } return problems }

failureSeverityPropagation

Field

Description

Name

Failure exceeds every propagation target's severity

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH INFO

Contract and evidence

At least one propagation target shall have severity greater than or equal to the source failure's severity (HIGH on the source). A target above all its classified incoming failures receives INFO. Missing links and severity values are checked by separate completeness rules; non-finite values are handled by the severity-value rule.

Corrective action

Trace the source failure's effect to its parent failure. Correct propagatesTo or the justified severity values so at least one target represents an effect at least as severe as the source.

Dispatch input

Analysis; once per viewpoint: false.

Kotlin declaration

com.stigway.metamodels.create.analysis.FailureSeverityPropagationRule

Kotlin implementation

com.stigway.metamodels.create.analysis.FailureSeverityPropagationRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/analysis/AnalysisRules.kt:

override fun check(container: MetamodelEntity): List<ModelProblem> { val problems = mutableListOf<ModelProblem>() for (ipa in container.allInterfacePointAnalyses()) { for (failure in ipa.allFailures()) { val index = ModelIndex.current() classificationDifference( this, index, ClassificationValue(failure, failure.severity?.value?.takeIf { it.failureSeverityClass != null }), index.incomingFailures(failure).map { source -> ClassificationValue(source, source.severity?.value?.takeIf { it.failureSeverityClass != null }) }, "severity", "incoming failures", ) { index.ownerElement(failure)?.let(index::classificationContributionElements).orEmpty() }?.let(problems::add) val failSev = failure.severity?.value?.takeIf { it.isFinite() } ?: continue if (failure.propagatesTo.isEmpty()) continue val targetSevs = failure.propagatesTo.mapNotNull { it.severity?.value?.takeIf { value -> value.isFinite() } } if (targetSevs.isEmpty()) continue if (targetSevs.none { it >= failSev }) { val maxTargetSeverity = targetSevs.max() problems += ModelProblem( rule = this, severity = defaultSeverity, entityName = failure.id, message = "${failure.idLabel} has severity $failSev but no propagatesTo target has severity ≥ $failSev.", remediation = "Set failure ${failure.idLabel} to `severity = ${severityExpr(maxTargetSeverity).text}`. " + "This is the highest severity available from its propagation targets. If the " + "propagation relation is wrong, remove or replace the `propagatesTo` " + "references on this failure.", remediationSummary = "Set `severity = ${severityExpr(maxTargetSeverity).text}` to match the highest propagation-target severity, or correct an incorrect `propagatesTo` relation.", quickFixes = listOf(SetArgumentFix(failure.id, "severity", severityExpr(maxTargetSeverity))) + failure.propagatesTo.map { RemoveListItemFix(failure.id, "propagatesTo", failureExpr(it)) }, ) } } } return problems }

failureMultiplicityPropagation

Field

Description

Name

Single-point failure propagates to a failure with incompatible multiplicity

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH

Contract and evidence

If a failure has multiplicity SINGLE_POINT, all its propagation targets shall also be SINGLE_POINT.

Corrective action

Trace each propagation from the single-point failure and classify the corresponding target effect as single-point. Correct the source classification or target links if the evidence describes a different failure combination.

Dispatch input

Analysis; once per viewpoint: false.

Kotlin declaration

com.stigway.metamodels.create.analysis.FailureMultiplicityPropagationRule

Kotlin implementation

com.stigway.metamodels.create.analysis.FailureMultiplicityPropagationRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/analysis/AnalysisRules.kt:

override fun check(container: MetamodelEntity): List<ModelProblem> { val problems = mutableListOf<ModelProblem>() for (ipa in container.allInterfacePointAnalyses()) { for (failure in ipa.allFailures()) { if (failure.multiplicity != Multiplicity.SINGLE_POINT) continue val violators = failure.propagatesTo.filter { it.multiplicity != null && it.multiplicity != Multiplicity.SINGLE_POINT } if (violators.isNotEmpty()) { val violatorLabels = violators.joinToString(", ") { it.idLabel } problems += ModelProblem( rule = this, severity = defaultSeverity, entityName = failure.id, message = "${failure.idLabel} is SINGLE_POINT but propagatesTo includes MULTIPLE_POINT failures: $violatorLabels.", remediation = "Change source failure ${failure.idLabel} from `Multiplicity.SINGLE_POINT` " + "if it is not a single-point failure, or remove/replace the " + "`propagatesTo` entries that point to non-SINGLE_POINT targets: " + violatorLabels + ". Do not reclassify target failures only to satisfy this source.", quickFixes = listOf( SetArgumentFix( failure.id, "multiplicity", FixExpression("Multiplicity.MULTIPLE_POINT") ) ) + violators.map { RemoveListItemFix(failure.id, "propagatesTo", failureExpr(it)) }, ) } } } return problems }

failureMultiplePointIndependent

Field

Description

Name

Multiple-point failure cites no independent failure

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH

Contract and evidence

A MULTIPLE_POINT failure with severity at or above S10, or missing severity, shall reference at least one independent failure that can violate the safety goal in combination with it. A severity explicitly below S10 exempts this reference requirement, regardless of ASIL.

Corrective action

Add the identified independent failures to independentFailures and document how their combination can violate the safety goal. Confirm the multiplicity classification if no such combination exists.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.analysis.FailureMultiplePointIndependentRule

Kotlin implementation

com.stigway.metamodels.create.analysis.FailureMultiplePointIndependentRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/analysis/AnalysisRules.kt:

class FailureMultiplePointIndependentRule : RequiredAttributeRule<Failure>( Failure::class, Viewpoint.ANALYSIS, "independentFailures", FixValueKind.FAILURE_REFERENCE, listArgument = true, missing = { it.multiplicity == Multiplicity.MULTIPLE_POINT && it.severity?.value?.let { severity -> severity < Severity.S10.value } != true && it.independentFailures.isEmpty() }, ) { override val name = "Multiple-point failure cites no independent failure" override val description = "A MULTIPLE_POINT failure with severity at or above S10, or missing severity, shall reference at least " + "one independent failure that can violate the safety goal in combination with it. " + "A severity explicitly below S10 exempts this reference requirement, regardless of ASIL." override val remediation = "Add the identified independent failures to `independentFailures` and document how their combination " + "can violate the safety goal. Confirm the `multiplicity` classification if no such combination exists." }

com.stigway.metamodels.create.RequiredAttributeRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/RequiredAttributeRule.kt:

override fun check(index: ModelIndex): List<ModelProblem> = index.subjectEntities .filter { type.java.isInstance(it) && missing(type.java.cast(it)) } .map { entity -> ModelProblem( rule = this, severity = defaultSeverity, entityName = entity.id, ownerElementId = index.ownerElement(entity)?.id, message = "${entity.idLabel} has no required $attribute value.", remediation = "Set $attribute on ${entity.idLabel} from the model's engineering evidence.", quickFixes = if (valueKind == FixValueKind.MULTIPLICITY) { Multiplicity.entries.map { SetArgumentFix( entity.id, attribute, FixExpression("Multiplicity.${it.name}") ) } } else listOf(PromptSetArgumentFix(entity.id, attribute, valueKind, listArgument = listArgument)), ) }

failureIndependentReference

Field

Description

Name

Failure cites an invalid independent failure

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH MODERATE

Contract and evidence

Independent failures shall belong to different elements with no ancestor-descendant relationship (HIGH). Self-reference is invalid. A SINGLE_POINT failure should not supply independentFailures (MODERATE).

Corrective action

Use failures on separate element branches in independentFailures; remove self-references and references on the same element or an ancestor or descendant. For a single-point failure, remove independent-failure references; if the failure is actually multiple-point, correct multiplicity using the analysis evidence.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.analysis.FailureIndependentReferenceRule

Kotlin implementation

com.stigway.metamodels.create.analysis.FailureIndependentReferenceRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/analysis/AnalysisBoundaryRules.kt:

override fun check(index: ModelIndex): List<ModelProblem> = index.subjectFailures.flatMap { failure -> buildList { if (failure in failure.independentFailures) { add( ModelProblem( this@FailureIndependentReferenceRule, defaultSeverity, "${failure.idLabel} references itself in independentFailures.", entityName = failure.id ) ) } failure.independentFailures.distinct().filter { it !== failure }.forEach { independent -> val sourceElement = index.ownerElement(failure) val targetElement = index.ownerElement(independent) if (sourceElement != null && targetElement != null && !index.independentElements( failure, independent ) ) { add( ModelProblem( this@FailureIndependentReferenceRule, defaultSeverity, "${failure.idLabel} names ${independent.idLabel} as independent, but their elements are " + "the same or have an ancestor-descendant relationship.", entityName = failure.id, ownerElementId = sourceElement.id, relatedEntityIds = listOf(independent.id), subjectId = "${failure.id}#independent:${independent.id}", ) ) } } if (failure.multiplicity == Multiplicity.SINGLE_POINT && failure.independentFailures.isNotEmpty()) { add( ModelProblem( this@FailureIndependentReferenceRule, ProblemSeverity.MODERATE, "${failure.idLabel} is SINGLE_POINT but supplies independentFailures.", entityName = failure.id ) ) } } }

failureChildPropagationCoverage

Field

Description

Name

Failure lacks a contributing child failure

Contributor unknown

true

Default severity

HIGH

Possible finding severities

HIGH

Contract and evidence

For every failure above bottom level, at least one failure in a Design-declared analysis child shall declare a valid propagatesTo link to it. A child with absent or disabled Analysis is bypassed once through its own Design.children. Each Design child shall reference its declaring element as parent. Missing coverage is HIGH. Bottom-level elements are outside this completeness check.

Corrective action

Add this failure to propagatesTo on at least one contributing failure in a Design-declared analysis child. Check the child-parent declarations and allow only one absent or disabled Analysis level.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.analysis.FailureChildPropagationCoverageRule

Kotlin implementation

com.stigway.metamodels.create.analysis.FailureChildPropagationCoverageRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/analysis/FailureChildPropagationCoverageRule.kt:

override fun check(index: ModelIndex): List<ModelProblem> = index.subjectFailures.mapNotNull { target -> val element = index.ownerElement(target) ?: return@mapNotNull null if (element.isBottomLevel || target.ownerInterfacePointAnalysis?.ownerAnalysis?.enabled == false) return@mapNotNull null val children = index.analysisChildrenOf(element) val knownIncoming = index.incomingFailures(target) val incoming = knownIncoming.filter { index.ownerElement(it) in children } when { incoming.any { index.validContribution(it, target) } -> null else -> ModelProblem( this, defaultSeverity, (if (knownIncoming.isEmpty()) { "No failure references ${target.idLabel} in its `propagatesTo` list. " } else { "Failures ${knownIncoming.joinToString { it.idLabel }} reference ${target.idLabel} " + "in `propagatesTo`, but none provides a valid contribution from a Design-declared analysis child. " }) + contributionChildrenDescription(index, element, children), entityName = target.id, ownerElementId = element.id, remediation = target.ownerInterfacePointAnalysis?.let { incomingContributionRemediation(index, it, target) }, remediationInventory = target.ownerInterfacePointAnalysis?.let { incomingContributionInventory( index, it ) }, remediationSummary = "Add this failure to `propagatesTo` on a contributing child failure, and link that child's interface-point analysis through `usedIn`.", ) } }

interfacePointAnalysisChildContributionCoverage

Field

Description

Name

Interface-point analysis lacks a contributing child analysis

Contributor unknown

true

Default severity

HIGH

Possible finding severities

HIGH

Contract and evidence

For every interface-point analysis above bottom level, at least one interface-point analysis in a Design-declared analysis child shall declare a valid usedIn link to its analysed interface point. An analysis decomposed into member analyses without direct failures delegates required coverage to its members. A child with absent or disabled Analysis is bypassed once through its own Design.children. Each Design child shall reference its declaring element as parent. Missing coverage is HIGH. Bottom-level elements are outside this completeness check.

Corrective action

Add this analysed interface point to usedIn on at least one contributing child interface-point analysis. Check the Design child-parent declarations and allow only one absent or disabled Analysis level.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.analysis.InterfacePointAnalysisChildContributionCoverageRule

Kotlin implementation

com.stigway.metamodels.create.analysis.InterfacePointAnalysisChildContributionCoverageRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/analysis/InterfacePointAnalysisChildContributionCoverageRule.kt:

override fun check(index: ModelIndex): List<ModelProblem> = index.subjectInterfaceAnalyses.mapNotNull { target -> val element = target.ownerAnalysis?.element ?: return@mapNotNull null if (element.isBottomLevel || target.ownerAnalysis?.enabled == false) return@mapNotNull null val children = index.analysisChildrenOf(element) val knownIncoming = index.incomingChildAnalyses(target) val incoming = knownIncoming.filter { it.ownerAnalysis?.element in children } when { target.isDecomposed() || incoming.any { index.validContribution( it, target ) } -> null else -> ModelProblem( this, defaultSeverity, (if (knownIncoming.isEmpty()) { "No interface-point analysis in an eligible analysis child references " + "${target.interfacePoint.idLabel} in `usedIn` for ${target.idLabel}. " } else { "Interface-point analyses ${knownIncoming.joinToString { it.idLabel }} reference " + "${target.interfacePoint.idLabel} in `usedIn`, but none provides a valid contribution " + "to ${target.idLabel} from a Design-declared analysis child. " }) + contributionChildrenDescription(index, element, children), entityName = target.id, ownerElementId = element.id, remediation = incomingContributionRemediation(index, target), remediationSummary = "Add this interface point to `usedIn` on at least one contributing child interface-point analysis.", remediationInventory = incomingContributionInventory(index, target), ) } }

failurePropagationToBottomLevel

Field

Description

Name

Failure propagates to a bottom-level failure

Contributor unknown

false

Default severity

MODERATE

Possible finding severities

MODERATE

Contract and evidence

A failure shall not declare propagatesTo links to failures in an enabled Analysis of a bottom-level element. Each invalid link is reported on the source failure that declares it.

Corrective action

Remove the propagation to the bottom-level failure, or correct the target element's isBottomLevel declaration when it does not match the agreed model scope.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.analysis.FailurePropagationToBottomLevelRule

Kotlin implementation

com.stigway.metamodels.create.analysis.FailurePropagationToBottomLevelRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/analysis/FailurePropagationToBottomLevelRule.kt:

override fun check(index: ModelIndex): List<ModelProblem> = index.subjectFailures.flatMap { source -> source.propagatesTo.distinct().mapNotNull { target -> val element = index.ownerElement(target) ?: return@mapNotNull null if (!element.isBottomLevel || target.ownerInterfacePointAnalysis?.ownerAnalysis?.enabled == false) { return@mapNotNull null } ModelProblem( this, defaultSeverity, "${source.idLabel} propagates to ${target.idLabel}, whose element ${element.idLabel} is bottom-level.", entityName = source.id, ownerElementId = index.ownerElement(source)?.id, relatedEntityIds = listOf(target.id), subjectId = "${source.id}#bottomLevelPropagation:${target.id}", ) } }

interfacePointAnalysisContributionToBottomLevel

Field

Description

Name

Interface-point analysis contributes to a bottom-level interface

Contributor unknown

false

Default severity

MODERATE

Possible finding severities

MODERATE

Contract and evidence

An interface-point analysis shall not declare a usedIn contribution to an interface analysed by its bottom-level analysis parent. Each invalid contribution is reported on the source analysis. Shared interface definitions retain the source's analysis parent.

Corrective action

Remove the usedIn contribution to the bottom-level interface, or correct the target element's isBottomLevel declaration when it does not match the agreed model scope.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.analysis.InterfacePointAnalysisContributionToBottomLevelRule

Kotlin implementation

com.stigway.metamodels.create.analysis.InterfacePointAnalysisContributionToBottomLevelRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/analysis/InterfacePointAnalysisContributionToBottomLevelRule.kt:

override fun check(index: ModelIndex): List<ModelProblem> = index.interfaceAnalyses.flatMap { target -> val analysis = target.ownerAnalysis ?: return@flatMap emptyList() if (!analysis.element.isBottomLevel || analysis.enabled == false) return@flatMap emptyList() index.incomingChildAnalyses(target).filter(index::isSubject).distinct().map { source -> ModelProblem( this, defaultSeverity, "${source.idLabel} references ${target.interfacePoint.idLabel} in usedIn for " + "${target.idLabel}, whose element ${analysis.element.idLabel} is bottom-level.", entityName = source.id, ownerElementId = source.ownerAnalysis?.element?.id, relatedEntityIds = listOf(target.id), subjectId = "${source.id}#bottomLevelContribution:${target.id}", ) } }

failurePropagationParentElement

Field

Description

Name

Failure propagates outside its eligible analysis parent

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH

Contract and evidence

Every propagatesTo target shall be a failure in an enabled analysis of the source element's analysis parent: its direct parent, or its grandparent when the direct parent's Analysis is absent or disabled. Only one level may be bypassed.

Corrective action

Point propagatesTo to a failure in the enabled analysis of the direct parent, or the grandparent when the direct parent's Analysis is absent or disabled. Remove self-links and links outside that hierarchy.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.analysis.FailurePropagationParentElementRule

Kotlin implementation

com.stigway.metamodels.create.analysis.FailurePropagationParentElementRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/analysis/AnalysisBoundaryRules.kt:

override fun check(index: ModelIndex): List<ModelProblem> = index.subjectFailures.flatMap { source -> val child = index.ownerElement(source) ?: return@flatMap emptyList() if (source.ownerInterfacePointAnalysis?.ownerAnalysis?.enabled == false || source.propagatesTo.isEmpty()) { return@flatMap emptyList() } val parent = index.analysisParentOf(child) source.propagatesTo.filter { target -> source === target || parent == null || index.ownerElement(target) !== parent || target.ownerInterfacePointAnalysis?.ownerAnalysis?.enabled == false }.map { target -> ModelProblem( this, defaultSeverity, "${source.idLabel} propagates to ${target.idLabel}, which is not a failure in an enabled analysis of its analysis parent (allowing one absent or disabled Analysis level).", entityName = source.id, ownerElementId = child.id, relatedEntityIds = listOf(target.id) ) } }

interfacePointAnalysisSubject

Field

Description

Name

Interface-point analysis references another element's interface

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH

Contract and evidence

An interface-point analysis shall analyse an interface point belonging to its Analysis's element, including service members and topics used through that element's ports.

Corrective action

Select an interfacePoint belonging to the analysed element, including a member or topic used through its ports. If the analysis belongs to another element, move it to that element's Analysis.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.analysis.InterfacePointAnalysisSubjectRule

Kotlin implementation

com.stigway.metamodels.create.analysis.InterfacePointAnalysisSubjectRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/analysis/AnalysisBoundaryRules.kt:

override fun check(index: ModelIndex): List<ModelProblem> = index.subjectInterfaceAnalyses.mapNotNull { analysis -> val element = analysis.ownerAnalysis?.element ?: return@mapNotNull null if (index.interfaceBelongsTo(analysis.interfacePoint, element)) return@mapNotNull null ModelProblem( this, defaultSeverity, "${analysis.idLabel} analyses an interface point outside ${element.idLabel}.", entityName = analysis.id, ownerElementId = element.id, relatedEntityIds = listOf(analysis.interfacePoint.id) ) }

Tests

testCaseMustLiveInTestCaseContainer

Field

Description

Name

Test case lacks a containing test specification

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH

Contract and evidence

Every TestCase shall be declared as a property of a Tests subclass; top-level val xxx = TestCase(...) declarations are not allowed.

Corrective action

Move the test case into the appropriate Tests subclass as a named val property, preserving its test data and links.

Dispatch input

MetamodelEntity; once per viewpoint: true.

Kotlin declaration

com.stigway.metamodels.create.tests.TestCaseMustLiveInTestCaseContainerRule

Kotlin implementation

com.stigway.metamodels.create.tests.TestCaseMustLiveInTestCaseContainerRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/tests/TestRules.kt:

override fun check(container: MetamodelEntity): List<ModelProblem> { return ModelIndex.current().subjectEntities .filterIsInstance<TestCase>() .filter { it.ownerContainer == null } .map { testCase -> val ref = testCase.idLabel val site = testCase.declaringClassName ?: "(unknown declaring class)" ModelProblem( rule = this, severity = defaultSeverity, entityName = testCase.id, message = "TestCase $ref is not declared inside any Tests " + "(declared at: $site). Move it into a `Tests` subclass " + "as a `val` property.", remediation = "Move test case $ref into the appropriate Tests as a " + "`val` property. Keep the test data unchanged unless the " + "free-floating declaration itself is the wrong test.", quickFixes = listOf( MoveDeclarationFix(testCase.id, MoveTargetKind.TEST_CASE_CONTAINER), ), ) } }

nonTestsEntityInTestsPackage

Field

Description

Name

Entity uses the wrong viewpoint package (Tests)

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH

Contract and evidence

A file under a .tests package may only declare tests-viewpoint entities (TestCase, Tests).

Corrective action

Move the declaration out of .tests into the viewpoint package appropriate for its entity type.

Dispatch input

MetamodelEntity; once per viewpoint: true.

Kotlin declaration

com.stigway.metamodels.create.NonTestsEntityInTestsPackageRule

Kotlin implementation

com.stigway.metamodels.create.NonTestsEntityInTestsPackageRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/ViewpointPackageRules.kt:

override fun check(container: MetamodelEntity): List<ModelProblem> = buildFindingsForViewpoint(this, Viewpoint.TESTS, "tests")

testsClassesTopLevel

Field

Description

Name

Tests class is nested inside another declaration

Contributor unknown

false

Default severity

MODERATE

Possible finding severities

MODERATE

Contract and evidence

Every class declared in this viewpoint shall be directly in its Kotlin file, outside other classes, objects and functions.

Corrective action

Move the class to file scope in the same Kotlin file. Update type references and pass any required enclosing state explicitly; retain the model's object containment.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.TestsClassesTopLevelRule

Kotlin implementation

com.stigway.metamodels.create.TestsClassesTopLevelRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/ViewpointDeclarationRules.kt:

class TestsClassesTopLevelRule : ViewpointClassesTopLevelRule(Viewpoint.TESTS) { override val name = "Tests class is nested inside another declaration" }

com.stigway.metamodels.create.ViewpointClassesTopLevelRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/ViewpointDeclarationRules.kt:

override fun check(index: ModelIndex): List<ModelProblem> = index.sourceFindings(this) { _, declaration -> if (declaration.kind == KotlinDeclarationKind.CLASS && !declaration.topLevel) "Class [${declaration.qualifiedName}] is nested; it shall be declared at file scope." else null }

testsClassInstance

Field

Description

Name

Tests class has no instance property in its file

Contributor unknown

false

Default severity

MODERATE

Possible finding severities

MODERATE

Contract and evidence

Every concrete class in this viewpoint shall have at least one instance property in the same Kotlin file, either at file scope or as a member of a class or object. Multiple instances are allowed. Function-local variables do not satisfy this obligation. Abstract, sealed, enum, annotation and expect classes and interfaces are exempt.

Corrective action

Declare an instance property in the same Kotlin file (for example, val abc = ABC()), either at file scope or as a field of its owning model class or object. Keep member instances in their owning container; multiple instances of the same class are allowed.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.TestsClassInstanceRule

Kotlin implementation

com.stigway.metamodels.create.TestsClassInstanceRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/ViewpointDeclarationRules.kt:

class TestsClassInstanceRule : ViewpointClassInstanceRule(Viewpoint.TESTS) { override val name = "Tests class has no instance property in its file" }

com.stigway.metamodels.create.ViewpointClassInstanceRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/ViewpointDeclarationRules.kt:

override fun check(index: ModelIndex): List<ModelProblem> { val counts = index.sourceFiles.filter { it.viewpoint == viewpoint }.associateWith { source -> val classes = source.declarations.filter { it.kind == KotlinDeclarationKind.CLASS } .mapTo(hashSetOf()) { it.qualifiedName } source.declarations.filter { it.kind == KotlinDeclarationKind.PROPERTY && (it.topLevel || it.memberProperty) } .mapNotNull { property -> val constructed = property.constructedType?.let { source.typeName(it, property) } constructed?.takeIf { it in classes } ?: property.declaredType?.let { source.typeName(it, property) } }.groupingBy { it }.eachCount() } return index.sourceFindings(this) { source, declaration -> if (!declaration.concrete) return@sourceFindings null val instances = counts.getValue(source)[declaration.qualifiedName] ?: 0 if (instances > 0) null else "Class [${declaration.qualifiedName}] has no instance property in this file; declare one at file scope or as a member of its owning class or object." } }

testsClassPascalCase

Field

Description

Name

Tests class name violates PascalCase

Contributor unknown

false

Default severity

MODERATE

Possible finding severities

MODERATE

Contract and evidence

Class identifiers in this viewpoint shall start with an uppercase letter and contain only letters and digits (PascalCase).

Corrective action

Rename the class to PascalCase with the IDE's Rename refactoring, removing underscores and dashes, and update every type and constructor reference.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.TestsClassPascalCaseRule

Kotlin implementation

com.stigway.metamodels.create.TestsClassPascalCaseRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/ViewpointDeclarationRules.kt:

class TestsClassPascalCaseRule : ViewpointClassPascalCaseRule(Viewpoint.TESTS) { override val name = "Tests class name violates PascalCase" }

com.stigway.metamodels.create.ViewpointClassPascalCaseRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/ViewpointDeclarationRules.kt:

override fun check(index: ModelIndex): List<ModelProblem> = index.sourceFindings(this) { _, declaration -> if (declaration.kind == KotlinDeclarationKind.CLASS && !ModelDeclarationNames.pascalCase(declaration.name)) "Class [${declaration.qualifiedName}] is not PascalCase." else null }

testsObjectCamelCase

Field

Description

Name

Tests instance name violates camelCase

Contributor unknown

false

Default severity

MODERATE

Possible finding severities

MODERATE

Contract and evidence

Instance property and named object identifiers in this viewpoint shall start with a lowercase letter and contain only letters and digits (camelCase). Context declarations of ProvidedMethod and RequiredMethod, including derived types, retain the external API identifier.

Corrective action

Rename the property or named object to camelCase with the IDE's Rename refactoring, removing underscores and dashes. Update references and any configured or persisted model IDs affected by the rename.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.TestsObjectCamelCaseRule

Kotlin implementation

com.stigway.metamodels.create.TestsObjectCamelCaseRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/ViewpointDeclarationRules.kt:

class TestsObjectCamelCaseRule : ViewpointObjectCamelCaseRule(Viewpoint.TESTS) { override val name = "Tests instance name violates camelCase" }

com.stigway.metamodels.create.ViewpointObjectCamelCaseRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/ViewpointDeclarationRules.kt:

override fun check(index: ModelIndex): List<ModelProblem> { val externalMethods = if (viewpoint == Viewpoint.CONTEXT) index.directMethodDeclarations() else emptySet() return index.sourceFindings(this) { _, declaration -> if (declaration.kind in setOf(KotlinDeclarationKind.PROPERTY, KotlinDeclarationKind.OBJECT) && declaration.qualifiedName !in externalMethods && !ModelDeclarationNames.camelCase(declaration.name) ) "Object [${declaration.qualifiedName}] is not camelCase." else null } }

nameDefinedInTestsPackage

Field

Description

Name

Tests entity has no required name

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH

Contract and evidence

Every tests entity shall have a non-blank name.

Corrective action

Give the test or test container a short name in its name.

Dispatch input

MetamodelEntity; once per viewpoint: true.

Kotlin declaration

com.stigway.metamodels.create.NameDefinedInTestsPackageRule

Kotlin implementation

com.stigway.metamodels.create.NameDefinedInTestsPackageRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/MetamodelPresenceRules.kt:

override fun check(container: MetamodelEntity): List<ModelProblem> = missingNameFindings(this, Viewpoint.TESTS)

descriptionDefinedInTestsPackage

Field

Description

Name

Tests entity has no required description

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH

Contract and evidence

Every tests entity except Tests shall have a non-blank description. Tests descriptions are optional.

Corrective action

Describe the test case's purpose, setup, stimulus, and expected outcome in its description.

Dispatch input

MetamodelEntity; once per viewpoint: true.

Kotlin declaration

com.stigway.metamodels.create.DescriptionDefinedInTestsPackageRule

Kotlin implementation

com.stigway.metamodels.create.DescriptionDefinedInTestsPackageRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/MetamodelPresenceRules.kt:

override fun check(container: MetamodelEntity): List<ModelProblem> = missingDescriptionFindings(this, Viewpoint.TESTS)

testCaseAsilDefined

Field

Description

Name

Test case has no ASIL

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH

Contract and evidence

Every TestCase shall define its required asil attribute.

Corrective action

Set the asil of TestCase using the applicable engineering evidence.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.tests.TestCaseAsilDefinedRule

Kotlin implementation

com.stigway.metamodels.create.tests.TestCaseAsilDefinedRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/tests/TestRules.kt:

class TestCaseAsilDefinedRule : RequiredAttributeRule<TestCase>( TestCase::class, Viewpoint.TESTS, "asil", FixValueKind.ASIL, missing = { it.asil == null }, ) { override val name = "Test case has no ASIL" }

com.stigway.metamodels.create.RequiredAttributeRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/RequiredAttributeRule.kt:

override fun check(index: ModelIndex): List<ModelProblem> = index.subjectEntities .filter { type.java.isInstance(it) && missing(type.java.cast(it)) } .map { entity -> ModelProblem( rule = this, severity = defaultSeverity, entityName = entity.id, ownerElementId = index.ownerElement(entity)?.id, message = "${entity.idLabel} has no required $attribute value.", remediation = "Set $attribute on ${entity.idLabel} from the model's engineering evidence.", quickFixes = if (valueKind == FixValueKind.MULTIPLICITY) { Multiplicity.entries.map { SetArgumentFix( entity.id, attribute, FixExpression("Multiplicity.${it.name}") ) } } else listOf(PromptSetArgumentFix(entity.id, attribute, valueKind, listArgument = listArgument)), ) }

testCaseContainerElementDefined

Field

Description

Name

Test specification has no subject element

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH

Contract and evidence

Every Tests shall define its required element attribute.

Corrective action

Set the element of Tests using the applicable engineering evidence.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.TestCaseContainerElementDefinedRule

Kotlin implementation

com.stigway.metamodels.create.TestCaseContainerElementDefinedRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/RequiredAttributeRule.kt:

class TestCaseContainerElementDefinedRule : RequiredAttributeRule<Tests>( Tests::class, Viewpoint.TESTS, "element", FixValueKind.ELEMENT_REFERENCE, missing = { ModelIndex.current().ownerElement(it) == null }, ) { override val name = "Test specification has no subject element" }

com.stigway.metamodels.create.RequiredAttributeRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/RequiredAttributeRule.kt:

override fun check(index: ModelIndex): List<ModelProblem> = index.subjectEntities .filter { type.java.isInstance(it) && missing(type.java.cast(it)) } .map { entity -> ModelProblem( rule = this, severity = defaultSeverity, entityName = entity.id, ownerElementId = index.ownerElement(entity)?.id, message = "${entity.idLabel} has no required $attribute value.", remediation = "Set $attribute on ${entity.idLabel} from the model's engineering evidence.", quickFixes = if (valueKind == FixValueKind.MULTIPLICITY) { Multiplicity.entries.map { SetArgumentFix( entity.id, attribute, FixExpression("Multiplicity.${it.name}") ) } } else listOf(PromptSetArgumentFix(entity.id, attribute, valueKind, listArgument = listArgument)), ) }

testCaseElementUnderTest

Field

Description

Name

Test case identifies no element under test

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH

Contract and evidence

Every TestCase shall define its required elementsUnderTest attribute.

Corrective action

Set the elementsUnderTest of TestCase using the applicable engineering evidence.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.tests.TestCaseElementUnderTestRule

Kotlin implementation

com.stigway.metamodels.create.tests.TestCaseElementUnderTestRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/tests/TestRules.kt:

class TestCaseElementUnderTestRule : RequiredAttributeRule<TestCase>( TestCase::class, Viewpoint.TESTS, "elementsUnderTest", FixValueKind.ELEMENT_REFERENCE, listArgument = true, missing = { it.elementsUnderTest.isEmpty() }, ) { override val name = "Test case identifies no element under test" }

com.stigway.metamodels.create.RequiredAttributeRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/RequiredAttributeRule.kt:

override fun check(index: ModelIndex): List<ModelProblem> = index.subjectEntities .filter { type.java.isInstance(it) && missing(type.java.cast(it)) } .map { entity -> ModelProblem( rule = this, severity = defaultSeverity, entityName = entity.id, ownerElementId = index.ownerElement(entity)?.id, message = "${entity.idLabel} has no required $attribute value.", remediation = "Set $attribute on ${entity.idLabel} from the model's engineering evidence.", quickFixes = if (valueKind == FixValueKind.MULTIPLICITY) { Multiplicity.entries.map { SetArgumentFix( entity.id, attribute, FixExpression("Multiplicity.${it.name}") ) } } else listOf(PromptSetArgumentFix(entity.id, attribute, valueKind, listArgument = listArgument)), ) }

testCaseInterfacesUnderTest

Field

Description

Name

Test case identifies no interface under test

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH

Contract and evidence

Every TestCase shall define its required interfacesUnderTest attribute.

Corrective action

Set the interfacesUnderTest of TestCase using the applicable engineering evidence.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.tests.TestCaseInterfacesUnderTestRule

Kotlin implementation

com.stigway.metamodels.create.tests.TestCaseInterfacesUnderTestRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/tests/TestRules.kt:

class TestCaseInterfacesUnderTestRule : RequiredAttributeRule<TestCase>( TestCase::class, Viewpoint.TESTS, "interfacesUnderTest", FixValueKind.INTERFACE_POINT_REFERENCE, listArgument = true, missing = { it.interfacesUnderTest.isEmpty() }, ) { override val name = "Test case identifies no interface under test" }

com.stigway.metamodels.create.RequiredAttributeRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/RequiredAttributeRule.kt:

override fun check(index: ModelIndex): List<ModelProblem> = index.subjectEntities .filter { type.java.isInstance(it) && missing(type.java.cast(it)) } .map { entity -> ModelProblem( rule = this, severity = defaultSeverity, entityName = entity.id, ownerElementId = index.ownerElement(entity)?.id, message = "${entity.idLabel} has no required $attribute value.", remediation = "Set $attribute on ${entity.idLabel} from the model's engineering evidence.", quickFixes = if (valueKind == FixValueKind.MULTIPLICITY) { Multiplicity.entries.map { SetArgumentFix( entity.id, attribute, FixExpression("Multiplicity.${it.name}") ) } } else listOf(PromptSetArgumentFix(entity.id, attribute, valueKind, listArgument = listArgument)), ) }

testCaseGivenWhenThen

Field

Description

Name

Test case omits the required Given–When–Then sequence

Contributor unknown

false

Default severity

MODERATE

Possible finding severities

MODERATE

Contract and evidence

Test case description shall follow Given/When/Then format: start with 'Given', then contain 'When' and 'Then' in order.

Corrective action

Rewrite description in Given/When/Then order: first the preconditions, then the stimulus, and finally the expected outcome.

Dispatch input

Tests; once per viewpoint: false.

Kotlin declaration

com.stigway.metamodels.create.tests.TestCaseGivenWhenThenRule

Kotlin implementation

com.stigway.metamodels.create.tests.TestCaseGivenWhenThenRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/tests/TestRules.kt:

override fun check(container: MetamodelEntity): List<ModelProblem> { val problems = mutableListOf<ModelProblem>() for (tc in container.allTestCases()) { val desc = tc.description ?: continue val lower = desc.trimStart().lowercase() if (!lower.startsWith("given")) { problems += ModelProblem( rule = this, severity = defaultSeverity, entityName = tc.id, message = "${tc.idLabel} description does not start with 'Given'.", remediation = "Rewrite the description of test case ${tc.idLabel} so it starts with " + "`Given`, then states the `When` action and `Then` expected result.", quickFixes = listOf( RewriteStringArgumentFix(tc.id, "description", "Given ... When ... Then ..."), ), ) continue } val givenIdx = lower.indexOf("given") val whenIdx = lower.indexOf("when", givenIdx + 5) val thenIdx = if (whenIdx >= 0) lower.indexOf("then", whenIdx + 4) else -1 if (whenIdx < 0 || thenIdx < 0) { problems += ModelProblem( rule = this, severity = defaultSeverity, entityName = tc.id, message = "${tc.idLabel} description does not contain 'Given', 'When', 'Then' in the required order.", remediation = "Rewrite the description of test case ${tc.idLabel} in Given/When/Then " + "order: preconditions, stimulus, then expected outcome.", quickFixes = listOf( RewriteStringArgumentFix(tc.id, "description", "Given ... When ... Then ..."), ), ) } } return problems }

forbiddenWordsInTests

Field

Description

Name

Tests entity contains forbidden wording

Contributor unknown

false

Default severity

MODERATE

Possible finding severities

MODERATE

Contract and evidence

String attributes in the tests viewpoint shall not contain the configured forbidden words. The default list rejects placeholders, examples, non-exhaustive phrasing, fuzzy quantities/timing, and subjective quality terms. Check constructor attributes, including names, descriptions, arguments, comments, verification criteria, collections, and nested metadata. Match whole words/phrases without regard to case. Referenced model entities are checked in their own viewpoint and module scope. KDoc, source comments, generated identities, and enum names are not string attributes.

Corrective action

Replace the reported wording in the named attribute with precise, testable conditions and justified values. Obtain missing engineering decisions before completing the statement.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.ForbiddenWordsInTestsRule

Kotlin implementation

com.stigway.metamodels.create.ForbiddenWordsInTestsRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/ForbiddenWordsRules.kt:

class ForbiddenWordsInTestsRule : ForbiddenWordsInViewpointRule(Viewpoint.TESTS) { override val name = "Tests entity contains forbidden wording" }

com.stigway.metamodels.create.ForbiddenWordsInViewpointRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/ForbiddenWordsRules.kt:

final override fun check(index: ModelIndex): List<ModelProblem> = buildList { for (entity in index.subjectEntities.filter { index.viewpoint(it) == viewpoint }.sortedBy { it.id }) { for ((attribute, text) in modelStringAttributes(entity)) { val found = findForbiddenPhrases(text, phrases) if (found.isEmpty()) continue add( ModelProblem( rule = this@ForbiddenWordsInViewpointRule, severity = defaultSeverity, entityName = entity.id, subjectId = "${entity.id}:$attribute", message = "${entity.idLabel} contains forbidden words in `$attribute`: ${found.joinToString(", ")}.", remediation = "Replace the reported wording in `$attribute` on ${entity.idLabel} with precise, testable " + "conditions: ${found.joinToString(", ")}. Resolve missing engineering decisions " + "before using this text as released evidence.", quickFixes = if ('.' !in attribute && '[' !in attribute) { listOf(RewriteStringArgumentFix(entity.id, attribute, text)) } else emptyList(), ) ) } } }

testCaseVerifiesRequirement

Field

Description

Name

Test case identifies no requirement to verify

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH

Contract and evidence

Every TestCase shall define its required verifies attribute.

Corrective action

Set the verifies of TestCase using the applicable engineering evidence.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.tests.TestCaseVerifiesRequirementRule

Kotlin implementation

com.stigway.metamodels.create.tests.TestCaseVerifiesRequirementRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/tests/TestRules.kt:

class TestCaseVerifiesRequirementRule : RequiredAttributeRule<TestCase>( TestCase::class, Viewpoint.TESTS, "verifies", FixValueKind.REQUIREMENT_REFERENCE, listArgument = true, missing = { it.verifies.isEmpty() }, ) { override val name = "Test case identifies no requirement to verify" }

com.stigway.metamodels.create.RequiredAttributeRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/RequiredAttributeRule.kt:

override fun check(index: ModelIndex): List<ModelProblem> = index.subjectEntities .filter { type.java.isInstance(it) && missing(type.java.cast(it)) } .map { entity -> ModelProblem( rule = this, severity = defaultSeverity, entityName = entity.id, ownerElementId = index.ownerElement(entity)?.id, message = "${entity.idLabel} has no required $attribute value.", remediation = "Set $attribute on ${entity.idLabel} from the model's engineering evidence.", quickFixes = if (valueKind == FixValueKind.MULTIPLICITY) { Multiplicity.entries.map { SetArgumentFix( entity.id, attribute, FixExpression("Multiplicity.${it.name}") ) } } else listOf(PromptSetArgumentFix(entity.id, attribute, valueKind, listArgument = listArgument)), ) }

testCaseTraceability

Field

Description

Name

Test case has no trace to an element, interface, or requirement

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH

Contract and evidence

Test case shall have at least one of elementsUnderTest, interfacesUnderTest, or verifies (requirement) populated.

Corrective action

Populate verifies, elementsUnderTest, or interfacesUnderTest with the objects exercised by the test. Use verifies to link the requirements whose behavior it checks.

Dispatch input

Tests; once per viewpoint: false.

Kotlin declaration

com.stigway.metamodels.create.tests.TestCaseTraceabilityRule

Kotlin implementation

com.stigway.metamodels.create.tests.TestCaseTraceabilityRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/tests/TestRules.kt:

override fun check(container: MetamodelEntity): List<ModelProblem> { val problems = mutableListOf<ModelProblem>() for (tc in container.allTestCases()) { if (tc.elementsUnderTest.isEmpty() && tc.interfacesUnderTest.isEmpty() && tc.verifies.isEmpty()) { problems += ModelProblem( rule = this, severity = defaultSeverity, entityName = tc.id, message = "${tc.idLabel} has empty elementsUnderTest, interfacesUnderTest, and verifies (requirement).", remediation = "Define at least one traceability reference for test case ${tc.idLabel}: " + "`verifies`, `elementsUnderTest`, or `interfacesUnderTest`. Prefer " + "`verifies` when the test validates a STIG requirement.", quickFixes = listOf( PromptSetArgumentFix( tc.id, "verifies", FixValueKind.REQUIREMENT_REFERENCE, listArgument = true ), PromptSetArgumentFix( tc.id, "elementsUnderTest", FixValueKind.ELEMENT_REFERENCE, listArgument = true ), PromptSetArgumentFix( tc.id, "interfacesUnderTest", FixValueKind.INTERFACE_POINT_REFERENCE, listArgument = true ), ), ) } } return problems }

testCaseAllocationConsistency

Field

Description

Name

Test case exercises none of its verified requirements' allocated elements

Contributor unknown

false

Default severity

HIGH

Possible finding severities

HIGH

Contract and evidence

A TestCase's elementsUnderTest shall overlap with the union of the allocatedTo lists of the requirements it verifies. The test shall actually exercise an element that the verified requirements are allocated to.

Corrective action

Align elementsUnderTest with the elements allocated by the requirements in verifies. If the test checks different requirements, correct verifies to match its actual purpose.

Dispatch input

Tests; once per viewpoint: false.

Kotlin declaration

com.stigway.metamodels.create.tests.TestCaseAllocationConsistencyRule

Kotlin implementation

com.stigway.metamodels.create.tests.TestCaseAllocationConsistencyRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/tests/TestRules.kt:

override fun check(container: MetamodelEntity): List<ModelProblem> { val problems = mutableListOf<ModelProblem>() for (tc in container.allTestCases()) { if (tc.verifies.isEmpty()) continue if (tc.elementsUnderTest.isEmpty()) continue val allowedAllocation = tc.verifies .flatMap { it.allocatedTo } .toSet() if (allowedAllocation.isEmpty()) continue val tested = tc.elementsUnderTest.toSet() if (tested.any { it in allowedAllocation }) continue val identifier = tc.idLabel val testedLabel = tested.joinToString(", ") { it.idLabel } val allowedLabel = allowedAllocation.joinToString(", ") { it.idLabel } problems += ModelProblem( rule = this, severity = defaultSeverity, entityName = tc.id, message = "TestCase $identifier has elementsUnderTest: $testedLabel, but none of " + "these elements appear in the union of allocatedTo for its verifies " + "requirements ($allowedLabel). The test does not exercise any element " + "that its verified requirements are allocated to.", remediation = "Set `elementsUnderTest` on test case $identifier to include at least one " + "element allocated by the verified requirements: $allowedLabel. If " + "the test exercises different requirements, fix this test case's " + "`verifies` list instead.", quickFixes = allowedAllocation.map { AddListItemFix(tc.id, "elementsUnderTest", testElementExpr(it)) } + tc.verifies.map { RemoveListItemFix(tc.id, "verifies", testRequirementExpr(it)) }, ) } return problems }

Human or AI review rules

A human or AI reviews these rules against the model and supporting engineering evidence. STIG selects the review subjects; a pending review is neither a violation nor a pass.

Rule ID

Name

Possible finding severities

contextDescriptionActiveVoice

Context description violates active present wording

INFO

requirementsDescriptionActiveVoice

Requirements description violates active present wording

INFO

requirementDevelopmentLevelAppropriate

Requirement uses detail inappropriate for its subject

INFO

requirementGrammaticalCorrectness

Requirement contains grammar or spelling errors

INFO

requirementUnambiguous

Requirement allows conflicting interpretations

INFO

requirementComprehensible

Requirement obscures its meaning for intended readers

INFO

requirementAtomic

Requirement combines independently verifiable obligations

INFO

requirementInternallyConsistent

Requirement contradicts itself

INFO

requirementFeasible

Requirement exceeds feasible development constraints

INFO

requirementVerifiable

Requirement provides no feasible means of verification

INFO

requirementNeedJustified

Requirement lacks an identified need

INFO

requirementImplementationIndependent

Requirement imposes an unjustified solution

INFO

requirementComplete

Requirement omits information needed to assess its obligation

INFO

requirementApplicableStandardsConformance

Requirement violates an applicable standard or interface

INFO

requirementWritingConventionConformance

Requirement violates an approved writing convention

INFO

requirementCorrect

Requirement misrepresents its source need

INFO

requirementTimingConstraints

Requirement omits necessary timing constraints

INFO

requirementVerificationCriteriaAdequate

Requirement lacks adequate acceptance criteria

INFO

requirementSetNoInformationDuplication

Requirements document duplicates obligations

INFO

requirementSetExternallyConsistent

Requirements document contains conflicting obligations

INFO

designDescriptionActiveVoice

Design description violates active present wording

INFO

analysisDescriptionActiveVoice

Analysis description violates active present wording

INFO

testsDescriptionActiveVoice

Tests description violates active present wording

INFO

Context

contextDescriptionActiveVoice

Field

Description

Name

Context description violates active present wording

Contributor unknown

false

Default severity

MODERATE

Possible finding severities

INFO

Contract and evidence

Authored descriptive prose shall use active voice and simple present wording. Normative requirement clauses retain the recognized obligation, prohibition, recommendation, or permission modal.

Apply this to applicable CREATE descriptions, including Requirement.description, TestCase.description, container descriptions, and notes. Preserve shall, shall not, should, should not, and may where they express the intended normative meaning. An active “Controller shall clear…” clause is valid; do not weaken it to “Controller clears…” merely to satisfy a tense heuristic. A copular state such as “flag is active” is not passive voice.

Preserve Given/When/Then structure in tests. Review narrative clauses, not code, formulas, identifiers, quoted standard text, or literal historical evidence as though they were sentences the agent may freely rewrite. Do not require every heading or table cell to contain a verb.

Corrective action

Name the actor and rewrite the relevant clause in active present/modal form without changing responsibility, timing, normative force, or the underlying engineering behavior. If the actor is unknown, identify the missing decision.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.ContextDescriptionActiveVoiceRule

Kotlin implementation

com.stigway.metamodels.create.ContextDescriptionActiveVoiceRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/DescriptionRules.kt:

class ContextDescriptionActiveVoiceRule : DescriptionActiveVoiceRule(Viewpoint.CONTEXT) { override val name = "Context description violates active present wording" }

com.stigway.metamodels.create.DescriptionActiveVoiceRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/DescriptionRules.kt:

final override fun check(index: ModelIndex): List<ModelProblem> { val subjects = index.subjectEntities .filter { index.viewpoint(it) == viewpoint && it !is InterfacePointAnalysis } .sortedBy { it.id } if (subjects.isEmpty()) return noSubjects(index, "${viewpoint.name} description subjects") // Required-value rules own missing prose; wording can be reviewed once that prose exists. return subjects.filterNot { it.description.isNullOrBlank() }.map { entity -> review(index, entity) } }

Requirements

requirementsDescriptionActiveVoice

Field

Description

Name

Requirements description violates active present wording

Contributor unknown

false

Default severity

MODERATE

Possible finding severities

INFO

Contract and evidence

Authored descriptive prose shall use active voice and simple present wording. Normative requirement clauses retain the recognized obligation, prohibition, recommendation, or permission modal.

Apply this to applicable CREATE descriptions, including Requirement.description, TestCase.description, container descriptions, and notes. Preserve shall, shall not, should, should not, and may where they express the intended normative meaning. An active “Controller shall clear…” clause is valid; do not weaken it to “Controller clears…” merely to satisfy a tense heuristic. A copular state such as “flag is active” is not passive voice.

Preserve Given/When/Then structure in tests. Review narrative clauses, not code, formulas, identifiers, quoted standard text, or literal historical evidence as though they were sentences the agent may freely rewrite. Do not require every heading or table cell to contain a verb.

Corrective action

Name the actor and rewrite the relevant clause in active present/modal form without changing responsibility, timing, normative force, or the underlying engineering behavior. If the actor is unknown, identify the missing decision.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.RequirementsDescriptionActiveVoiceRule

Kotlin implementation

com.stigway.metamodels.create.RequirementsDescriptionActiveVoiceRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/DescriptionRules.kt:

class RequirementsDescriptionActiveVoiceRule : DescriptionActiveVoiceRule(Viewpoint.REQUIREMENTS) { override val name = "Requirements description violates active present wording" }

com.stigway.metamodels.create.DescriptionActiveVoiceRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/DescriptionRules.kt:

final override fun check(index: ModelIndex): List<ModelProblem> { val subjects = index.subjectEntities .filter { index.viewpoint(it) == viewpoint && it !is InterfacePointAnalysis } .sortedBy { it.id } if (subjects.isEmpty()) return noSubjects(index, "${viewpoint.name} description subjects") // Required-value rules own missing prose; wording can be reviewed once that prose exists. return subjects.filterNot { it.description.isNullOrBlank() }.map { entity -> review(index, entity) } }

requirementDevelopmentLevelAppropriate

Field

Description

Name

Requirement uses detail inappropriate for its subject

Contributor unknown

false

Default severity

MODERATE

Possible finding severities

INFO

Contract and evidence

A requirement's intent and level of detail shall be appropriate to the entity it specifies. It shall avoid unnecessary architecture/design constraints while allowing implementation independence to the extent possible.

Use Requirement.element, its role and Context, actual parent/child relations, and linked parent requirements. Element.level alone cannot decide whether a statement is appropriately abstract or whether HW/SW detail is necessary. Do not introduce new stakeholder/system/software requirement subclasses to perform this review.

Corrective action

Move detail to the appropriate existing requirement/design level or refine an underspecified requirement at its current level. Preserve constraints justified by parent obligations, applicable standards, or external interfaces. Identify the required engineering allocation before changing typed links.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.requirements.RequirementDevelopmentLevelAppropriateRule

Kotlin implementation

com.stigway.metamodels.create.requirements.RequirementDevelopmentLevelAppropriateRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/requirements/RequirementSemanticRules.kt:

class RequirementDevelopmentLevelAppropriateRule : RequirementSemanticRule() { override val name = "Requirement uses detail inappropriate for its subject" override val description = """ A requirement's intent and level of detail shall be appropriate to the entity it specifies. It shall avoid unnecessary architecture/design constraints while allowing implementation independence to the extent possible. Use `Requirement.element`, its role and Context, actual parent/child relations, and linked parent requirements. `Element.level` alone cannot decide whether a statement is appropriately abstract or whether HW/SW detail is necessary. Do not introduce new stakeholder/system/software requirement subclasses to perform this review. """.trimIndent() override val remediation = """ Move detail to the appropriate existing requirement/design level or refine an underspecified requirement at its current level. Preserve constraints justified by parent obligations, applicable standards, or external interfaces. Identify the required engineering allocation before changing typed links. """.trimIndent() }

com.stigway.metamodels.create.requirements.RequirementSemanticRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/requirements/RequirementSemanticRules.kt:

final override fun check(index: ModelIndex): List<ModelProblem> { if (index.subjectRequirements.isEmpty()) return noSubjects(index, "requirements") return index.subjectRequirements.filterNot { it.description.isNullOrBlank() || criteriaRequired && it.verificationCriteria.isNullOrBlank() }.sortedBy { it.id }.map { requirement -> val related = buildList { add(requirement.element.id) addAll(requirement.allocatedTo.map { it.id }) addAll(requirement.derivedFrom.map { it.id }) if (includeTestEvidence) { addAll( index.entities.filterIsInstance<TestCase>() .filter { requirement in it.verifies }.map { it.id }) } } review(index, requirement, relatedIds = related) } }

requirementGrammaticalCorrectness

Field

Description

Name

Requirement contains grammar or spelling errors

Contributor unknown

false

Default severity

MODERATE

Possible finding severities

INFO

Contract and evidence

A requirement's human-readable name, description, and verification criteria shall be grammatically and orthographically correct.

This entry is requirement-specific; it does not expand every requirement rule to tests. Allow concise title fragments, domain terminology, identifiers, formulas, and documented abbreviations. Missing required text is already covered by presence rules. Grammar correctness does not establish technical correctness or active voice.

Corrective action

Correct the language while preserving quantities, units, polarity, conditions, actors, and normative force. Ask for clarification when an apparent typo has more than one plausible engineering interpretation.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.requirements.RequirementGrammaticalCorrectnessRule

Kotlin implementation

com.stigway.metamodels.create.requirements.RequirementGrammaticalCorrectnessRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/requirements/RequirementSemanticRules.kt:

class RequirementGrammaticalCorrectnessRule : RequirementSemanticRule() { override val name = "Requirement contains grammar or spelling errors" override val description = """ A requirement's human-readable name, description, and verification criteria shall be grammatically and orthographically correct. This entry is requirement-specific; it does not expand every requirement rule to tests. Allow concise title fragments, domain terminology, identifiers, formulas, and documented abbreviations. Missing required text is already covered by presence rules. Grammar correctness does not establish technical correctness or active voice. """.trimIndent() override val remediation = """ Correct the language while preserving quantities, units, polarity, conditions, actors, and normative force. Ask for clarification when an apparent typo has more than one plausible engineering interpretation. """.trimIndent() }

com.stigway.metamodels.create.requirements.RequirementSemanticRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/requirements/RequirementSemanticRules.kt:

final override fun check(index: ModelIndex): List<ModelProblem> { if (index.subjectRequirements.isEmpty()) return noSubjects(index, "requirements") return index.subjectRequirements.filterNot { it.description.isNullOrBlank() || criteriaRequired && it.verificationCriteria.isNullOrBlank() }.sortedBy { it.id }.map { requirement -> val related = buildList { add(requirement.element.id) addAll(requirement.allocatedTo.map { it.id }) addAll(requirement.derivedFrom.map { it.id }) if (includeTestEvidence) { addAll( index.entities.filterIsInstance<TestCase>() .filter { requirement in it.verifies }.map { it.id }) } } review(index, requirement, relatedIds = related) } }

requirementUnambiguous

Field

Description

Name

Requirement allows conflicting interpretations

Contributor unknown

false

Default severity

MODERATE

Possible finding severities

INFO

Contract and evidence

A requirement shall have one clear, consistent interpretation in its defined engineering context.

Check actors, referents, triggers, quantifiers, limits, units, temporal order, and scope of negation. Resolve referenced definitions. A concise name may omit details but shall not imply a different obligation from the description. Existing modal, subject-position, and forbidden-word checks provide limited evidence; passing them does not prove that the statement is unambiguous.

Corrective action

Replace the ambiguous construction with a precise obligation using established definitions. Report the competing interpretations when the intended one is not established.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.requirements.RequirementUnambiguousRule

Kotlin implementation

com.stigway.metamodels.create.requirements.RequirementUnambiguousRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/requirements/RequirementSemanticRules.kt:

class RequirementUnambiguousRule : RequirementSemanticRule() { override val name = "Requirement allows conflicting interpretations" override val description = """ A requirement shall have one clear, consistent interpretation in its defined engineering context. Check actors, referents, triggers, quantifiers, limits, units, temporal order, and scope of negation. Resolve referenced definitions. A concise name may omit details but shall not imply a different obligation from the description. Existing modal, subject-position, and forbidden-word checks provide limited evidence; passing them does not prove that the statement is unambiguous. """.trimIndent() override val remediation = """ Replace the ambiguous construction with a precise obligation using established definitions. Report the competing interpretations when the intended one is not established. """.trimIndent() }

com.stigway.metamodels.create.requirements.RequirementSemanticRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/requirements/RequirementSemanticRules.kt:

final override fun check(index: ModelIndex): List<ModelProblem> { if (index.subjectRequirements.isEmpty()) return noSubjects(index, "requirements") return index.subjectRequirements.filterNot { it.description.isNullOrBlank() || criteriaRequired && it.verificationCriteria.isNullOrBlank() }.sortedBy { it.id }.map { requirement -> val related = buildList { add(requirement.element.id) addAll(requirement.allocatedTo.map { it.id }) addAll(requirement.derivedFrom.map { it.id }) if (includeTestEvidence) { addAll( index.entities.filterIsInstance<TestCase>() .filter { requirement in it.verifies }.map { it.id }) } } review(index, requirement, relatedIds = related) } }

requirementComprehensible

Field

Description

Name

Requirement obscures its meaning for intended readers

Contributor unknown

false

Default severity

MODERATE

Possible finding severities

INFO

Contract and evidence

The intended stakeholders and consumers shall be able to understand the requirement using the agreed domain vocabulary and supplied specification context.

Assess explanation, sentence structure, unexplained terminology, and the intended audience. This differs from requirement clarity: a statement can have a precise formal interpretation and still be inaccessible to its consumers. AI confidence alone does not establish that every stakeholder understands it.

Corrective action

Clarify the language and provide or reference necessary definitions without weakening the obligation or repeating shared definitions in every requirement.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.requirements.RequirementComprehensibleRule

Kotlin implementation

com.stigway.metamodels.create.requirements.RequirementComprehensibleRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/requirements/RequirementSemanticRules.kt:

class RequirementComprehensibleRule : RequirementSemanticRule() { override val name = "Requirement obscures its meaning for intended readers" override val description = """ The intended stakeholders and consumers shall be able to understand the requirement using the agreed domain vocabulary and supplied specification context. Assess explanation, sentence structure, unexplained terminology, and the intended audience. This differs from requirement clarity: a statement can have a precise formal interpretation and still be inaccessible to its consumers. AI confidence alone does not establish that every stakeholder understands it. """.trimIndent() override val remediation = """ Clarify the language and provide or reference necessary definitions without weakening the obligation or repeating shared definitions in every requirement. """.trimIndent() }

com.stigway.metamodels.create.requirements.RequirementSemanticRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/requirements/RequirementSemanticRules.kt:

final override fun check(index: ModelIndex): List<ModelProblem> { if (index.subjectRequirements.isEmpty()) return noSubjects(index, "requirements") return index.subjectRequirements.filterNot { it.description.isNullOrBlank() || criteriaRequired && it.verificationCriteria.isNullOrBlank() }.sortedBy { it.id }.map { requirement -> val related = buildList { add(requirement.element.id) addAll(requirement.allocatedTo.map { it.id }) addAll(requirement.derivedFrom.map { it.id }) if (includeTestEvidence) { addAll( index.entities.filterIsInstance<TestCase>() .filter { requirement in it.verifies }.map { it.id }) } } review(index, requirement, relatedIds = related) } }

requirementAtomic

Field

Description

Name

Requirement combines independently verifiable obligations

Contributor unknown

false

Default severity

MODERATE

Possible finding severities

INFO

Contract and evidence

At its specified hierarchical level, a requirement shall express one obligation that cannot usefully be split into independent requirements.

Consider whether parts can be independently satisfied, allocated, or verified at that level. A conjunction or several steps does not automatically make a requirement non-atomic: a condition and its response, a bounded range, or an inseparable response sequence can belong together. Independently required cooling, notification, and reboot behavior normally need separate obligations.

Corrective action

Split independently meaningful obligations and preserve their conditions and traceability. Review the effects on allocation and verification links; splitting text alone does not maintain those links.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.requirements.RequirementAtomicRule

Kotlin implementation

com.stigway.metamodels.create.requirements.RequirementAtomicRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/requirements/RequirementSemanticRules.kt:

class RequirementAtomicRule : RequirementSemanticRule() { override val name = "Requirement combines independently verifiable obligations" override val description = """ At its specified hierarchical level, a requirement shall express one obligation that cannot usefully be split into independent requirements. Consider whether parts can be independently satisfied, allocated, or verified at that level. A conjunction or several steps does not automatically make a requirement non-atomic: a condition and its response, a bounded range, or an inseparable response sequence can belong together. Independently required cooling, notification, and reboot behavior normally need separate obligations. """.trimIndent() override val remediation = """ Split independently meaningful obligations and preserve their conditions and traceability. Review the effects on allocation and verification links; splitting text alone does not maintain those links. """.trimIndent() }

com.stigway.metamodels.create.requirements.RequirementSemanticRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/requirements/RequirementSemanticRules.kt:

final override fun check(index: ModelIndex): List<ModelProblem> { if (index.subjectRequirements.isEmpty()) return noSubjects(index, "requirements") return index.subjectRequirements.filterNot { it.description.isNullOrBlank() || criteriaRequired && it.verificationCriteria.isNullOrBlank() }.sortedBy { it.id }.map { requirement -> val related = buildList { add(requirement.element.id) addAll(requirement.allocatedTo.map { it.id }) addAll(requirement.derivedFrom.map { it.id }) if (includeTestEvidence) { addAll( index.entities.filterIsInstance<TestCase>() .filter { requirement in it.verifies }.map { it.id }) } } review(index, requirement, relatedIds = related) } }

requirementInternallyConsistent

Field

Description

Name

Requirement contradicts itself

Contributor unknown

false

Default severity

MODERATE

Possible finding severities

INFO

Contract and evidence

A requirement shall contain no mutually contradictory conditions, obligations, bounds, or ordering constraints within its stated context.

Compare all clauses, definitions, and applicable conditions within that requirement. For example, requiring the same voltage to be above 100 V and below 50 V at the same instant makes that trigger inconsistent. Distinguish different times, explicitly stated mode conditions, or signals before alleging a contradiction. Contradictions between requirements belong to the external consistency rule.

Corrective action

Resolve the conflicting clauses or values using authoritative engineering intent; do not select a threshold or delete a clause arbitrarily.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.requirements.RequirementInternallyConsistentRule

Kotlin implementation

com.stigway.metamodels.create.requirements.RequirementInternallyConsistentRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/requirements/RequirementSemanticRules.kt:

class RequirementInternallyConsistentRule : RequirementSemanticRule() { override val name = "Requirement contradicts itself" override val description = """ A requirement shall contain no mutually contradictory conditions, obligations, bounds, or ordering constraints within its stated context. Compare all clauses, definitions, and applicable conditions within that requirement. For example, requiring the same voltage to be above 100 V and below 50 V at the same instant makes that trigger inconsistent. Distinguish different times, explicitly stated mode conditions, or signals before alleging a contradiction. Contradictions between requirements belong to the external consistency rule. """.trimIndent() override val remediation = """ Resolve the conflicting clauses or values using authoritative engineering intent; do not select a threshold or delete a clause arbitrarily. """.trimIndent() }

com.stigway.metamodels.create.requirements.RequirementSemanticRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/requirements/RequirementSemanticRules.kt:

final override fun check(index: ModelIndex): List<ModelProblem> { if (index.subjectRequirements.isEmpty()) return noSubjects(index, "requirements") return index.subjectRequirements.filterNot { it.description.isNullOrBlank() || criteriaRequired && it.verificationCriteria.isNullOrBlank() }.sortedBy { it.id }.map { requirement -> val related = buildList { add(requirement.element.id) addAll(requirement.allocatedTo.map { it.id }) addAll(requirement.derivedFrom.map { it.id }) if (includeTestEvidence) { addAll( index.entities.filterIsInstance<TestCase>() .filter { requirement in it.verifies }.map { it.id }) } } review(index, requirement, relatedIds = related) } }

requirementFeasible

Field

Description

Name

Requirement exceeds feasible development constraints

Contributor unknown

false

Default severity

MODERATE

Possible finding severities

INFO

Contract and evidence

A requirement shall be realizable within the applicable technical, resource, cost, schedule, and other development constraints, with acceptable engineering risk.

Use identified constraints, available technology, relevant analysis, and the subject's responsibilities. An extreme bound such as restart and reinitialization within 0.0001 us warrants scrutiny, but text plausibility alone is not evidence of feasibility or infeasibility. A missing feasibility argument or unavailable constraints leave the assessment open.

Corrective action

Identify the conflicting constraint and obtain an engineering decision on the requirement, resources, architecture, or development plan. Do not silently relax performance or safety limits.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.requirements.RequirementFeasibleRule

Kotlin implementation

com.stigway.metamodels.create.requirements.RequirementFeasibleRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/requirements/RequirementSemanticRules.kt:

class RequirementFeasibleRule : RequirementSemanticRule() { override val name = "Requirement exceeds feasible development constraints" override val description = """ A requirement shall be realizable within the applicable technical, resource, cost, schedule, and other development constraints, with acceptable engineering risk. Use identified constraints, available technology, relevant analysis, and the subject's responsibilities. An extreme bound such as restart and reinitialization within `0.0001 us` warrants scrutiny, but text plausibility alone is not evidence of feasibility or infeasibility. A missing feasibility argument or unavailable constraints leave the assessment open. """.trimIndent() override val remediation = """ Identify the conflicting constraint and obtain an engineering decision on the requirement, resources, architecture, or development plan. Do not silently relax performance or safety limits. """.trimIndent() }

com.stigway.metamodels.create.requirements.RequirementSemanticRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/requirements/RequirementSemanticRules.kt:

final override fun check(index: ModelIndex): List<ModelProblem> { if (index.subjectRequirements.isEmpty()) return noSubjects(index, "requirements") return index.subjectRequirements.filterNot { it.description.isNullOrBlank() || criteriaRequired && it.verificationCriteria.isNullOrBlank() }.sortedBy { it.id }.map { requirement -> val related = buildList { add(requirement.element.id) addAll(requirement.allocatedTo.map { it.id }) addAll(requirement.derivedFrom.map { it.id }) if (includeTestEvidence) { addAll( index.entities.filterIsInstance<TestCase>() .filter { requirement in it.verifies }.map { it.id }) } } review(index, requirement, relatedIds = related) } }

requirementVerifiable

Field

Description

Name

Requirement provides no feasible means of verification

Contributor unknown

false

Default severity

MODERATE

Possible finding severities

INFO

Contract and evidence

Means shall be available at the requirement's specified level to demonstrate whether its obligation is fulfilled within the applicable verification constraints.

Consider the obligation, its verificationCriteria, observable outcomes, measurable limits where needed, and suitable test, analysis, inspection, or demonstration methods. “Ensure data security” or “detect overvoltage” lacks a sufficient decision basis unless the relevant properties or limits are explicitly defined elsewhere in the assessed specification.

THRESHOLD1 can be a valid referenced limit when its definition and units are available. Its name alone is not proof of measurability. Verifiability assesses whether a suitable verification method is available. Criteria adequacy assesses whether the requirement's criteria define a sufficient acceptance decision. Existing test trace links alone establish neither.

Corrective action

Define observable acceptance conditions and a credible verification approach at the stated level. Identify any unavailable measurement capability or unresolved definition.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.requirements.RequirementVerifiableRule

Kotlin implementation

com.stigway.metamodels.create.requirements.RequirementVerifiableRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/requirements/RequirementSemanticRules.kt:

class RequirementVerifiableRule : RequirementSemanticRule(includeTestEvidence = true) { override val name = "Requirement provides no feasible means of verification" override val description = """ Means shall be available at the requirement's specified level to demonstrate whether its obligation is fulfilled within the applicable verification constraints. Consider the obligation, its `verificationCriteria`, observable outcomes, measurable limits where needed, and suitable test, analysis, inspection, or demonstration methods. “Ensure data security” or “detect overvoltage” lacks a sufficient decision basis unless the relevant properties or limits are explicitly defined elsewhere in the assessed specification. `THRESHOLD1` can be a valid referenced limit when its definition and units are available. Its name alone is not proof of measurability. Verifiability assesses whether a suitable verification method is available. Criteria adequacy assesses whether the requirement's criteria define a sufficient acceptance decision. Existing test trace links alone establish neither. """.trimIndent() override val remediation = """ Define observable acceptance conditions and a credible verification approach at the stated level. Identify any unavailable measurement capability or unresolved definition. """.trimIndent() }

com.stigway.metamodels.create.requirements.RequirementSemanticRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/requirements/RequirementSemanticRules.kt:

final override fun check(index: ModelIndex): List<ModelProblem> { if (index.subjectRequirements.isEmpty()) return noSubjects(index, "requirements") return index.subjectRequirements.filterNot { it.description.isNullOrBlank() || criteriaRequired && it.verificationCriteria.isNullOrBlank() }.sortedBy { it.id }.map { requirement -> val related = buildList { add(requirement.element.id) addAll(requirement.allocatedTo.map { it.id }) addAll(requirement.derivedFrom.map { it.id }) if (includeTestEvidence) { addAll( index.entities.filterIsInstance<TestCase>() .filter { requirement in it.verifies }.map { it.id }) } } review(index, requirement, relatedIds = related) } }

requirementNeedJustified

Field

Description

Name

Requirement lacks an identified need

Contributor unknown

false

Default severity

MODERATE

Possible finding severities

INFO

Contract and evidence

A requirement shall express an essential capability, characteristic, constraint, or quality factor whose omission from the assessed specification would leave an unfulfilled identified need.

Use stakeholder/parent needs, applicable obligations, and the relevant requirement set. A derivedFrom link alone does not justify the obligation. Assess the contribution that would be lost if the requirement were omitted and whether another obligation already supplies it.

This immediate rule assesses justification within the stated review scope. Determining whether an obsolete requirement belongs in the active set requires the deferred lifecycle model and its dependent rules; do not infer that state from names, dates, missing links, or document status.

Corrective action

Establish the need or identify the unsupported/redundant obligation for an engineering decision. Preserve traceability and historical records. Report duplicated information under the information-uniqueness rule rather than issuing the same finding twice.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.requirements.RequirementNeedJustifiedRule

Kotlin implementation

com.stigway.metamodels.create.requirements.RequirementNeedJustifiedRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/requirements/RequirementSemanticRules.kt:

class RequirementNeedJustifiedRule : RequirementSemanticRule() { override val name = "Requirement lacks an identified need" override val description = """ A requirement shall express an essential capability, characteristic, constraint, or quality factor whose omission from the assessed specification would leave an unfulfilled identified need. Use stakeholder/parent needs, applicable obligations, and the relevant requirement set. A `derivedFrom` link alone does not justify the obligation. Assess the contribution that would be lost if the requirement were omitted and whether another obligation already supplies it. This immediate rule assesses justification within the stated review scope. Determining whether an obsolete requirement belongs in the active set requires the deferred lifecycle model and its dependent rules; do not infer that state from names, dates, missing links, or document status. """.trimIndent() override val remediation = """ Establish the need or identify the unsupported/redundant obligation for an engineering decision. Preserve traceability and historical records. Report duplicated information under the information-uniqueness rule rather than issuing the same finding twice. """.trimIndent() }

com.stigway.metamodels.create.requirements.RequirementSemanticRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/requirements/RequirementSemanticRules.kt:

final override fun check(index: ModelIndex): List<ModelProblem> { if (index.subjectRequirements.isEmpty()) return noSubjects(index, "requirements") return index.subjectRequirements.filterNot { it.description.isNullOrBlank() || criteriaRequired && it.verificationCriteria.isNullOrBlank() }.sortedBy { it.id }.map { requirement -> val related = buildList { add(requirement.element.id) addAll(requirement.allocatedTo.map { it.id }) addAll(requirement.derivedFrom.map { it.id }) if (includeTestEvidence) { addAll( index.entities.filterIsInstance<TestCase>() .filter { requirement in it.verifies }.map { it.id }) } } review(index, requirement, relatedIds = related) } }

requirementImplementationIndependent

Field

Description

Name

Requirement imposes an unjustified solution

Contributor unknown

false

Default severity

MODERATE

Possible finding severities

INFO

Contract and evidence

A requirement shall state the needed behavior, property, or justified constraint at the subject's boundary, leaving unnecessary solution choices to design.

Distinguish an arbitrary internal solution from a constraint required by a parent, a standard, an external interface, or the entity being specified. A hardware-interface requirement can legitimately name registers or a protocol. The development-level rule assesses where that detail belongs; this rule assesses whether the solution constraint is justified.

Corrective action

Move unjustified solution detail into Design or restate the required outcome. Retain and trace externally imposed or otherwise justified constraints.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.requirements.RequirementImplementationIndependentRule

Kotlin implementation

com.stigway.metamodels.create.requirements.RequirementImplementationIndependentRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/requirements/RequirementSemanticRules.kt:

class RequirementImplementationIndependentRule : RequirementSemanticRule() { override val name = "Requirement imposes an unjustified solution" override val description = """ A requirement shall state the needed behavior, property, or justified constraint at the subject's boundary, leaving unnecessary solution choices to design. Distinguish an arbitrary internal solution from a constraint required by a parent, a standard, an external interface, or the entity being specified. A hardware-interface requirement can legitimately name registers or a protocol. The development-level rule assesses where that detail belongs; this rule assesses whether the solution constraint is justified. """.trimIndent() override val remediation = """ Move unjustified solution detail into Design or restate the required outcome. Retain and trace externally imposed or otherwise justified constraints. """.trimIndent() }

com.stigway.metamodels.create.requirements.RequirementSemanticRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/requirements/RequirementSemanticRules.kt:

final override fun check(index: ModelIndex): List<ModelProblem> { if (index.subjectRequirements.isEmpty()) return noSubjects(index, "requirements") return index.subjectRequirements.filterNot { it.description.isNullOrBlank() || criteriaRequired && it.verificationCriteria.isNullOrBlank() }.sortedBy { it.id }.map { requirement -> val related = buildList { add(requirement.element.id) addAll(requirement.allocatedTo.map { it.id }) addAll(requirement.derivedFrom.map { it.id }) if (includeTestEvidence) { addAll( index.entities.filterIsInstance<TestCase>() .filter { requirement in it.verifies }.map { it.id }) } } review(index, requirement, relatedIds = related) } }

requirementComplete

Field

Description

Name

Requirement omits information needed to assess its obligation

Contributor unknown

false

Default severity

MODERATE

Possible finding severities

INFO

Contract and evidence

A requirement, together with its explicitly referenced definitions, shall sufficiently describe the capability, characteristic, constraint, or quality factor needed to understand and assess the obligation at its level.

Check applicable actors, triggers, outputs, bounds, units, timing, and necessary conditions in the assessed obligation. This is completeness of an individual statement, not completeness of the entire product requirement set or the deferred inventory of element modes and transitions. Typed references, a shared glossary, and defined symbolic limits may supply meaning; essential information must not depend on an unstated later conversation.

Corrective action

Supply the missing information from identified evidence or link its authoritative definition. Do not fill gaps with guessed product behavior or copy shared definitions into multiple requirements.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.requirements.RequirementCompleteRule

Kotlin implementation

com.stigway.metamodels.create.requirements.RequirementCompleteRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/requirements/RequirementSemanticRules.kt:

class RequirementCompleteRule : RequirementSemanticRule() { override val name = "Requirement omits information needed to assess its obligation" override val description = """ A requirement, together with its explicitly referenced definitions, shall sufficiently describe the capability, characteristic, constraint, or quality factor needed to understand and assess the obligation at its level. Check applicable actors, triggers, outputs, bounds, units, timing, and necessary conditions in the assessed obligation. This is completeness of an individual statement, not completeness of the entire product requirement set or the deferred inventory of element modes and transitions. Typed references, a shared glossary, and defined symbolic limits may supply meaning; essential information must not depend on an unstated later conversation. """.trimIndent() override val remediation = """ Supply the missing information from identified evidence or link its authoritative definition. Do not fill gaps with guessed product behavior or copy shared definitions into multiple requirements. """.trimIndent() }

com.stigway.metamodels.create.requirements.RequirementSemanticRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/requirements/RequirementSemanticRules.kt:

final override fun check(index: ModelIndex): List<ModelProblem> { if (index.subjectRequirements.isEmpty()) return noSubjects(index, "requirements") return index.subjectRequirements.filterNot { it.description.isNullOrBlank() || criteriaRequired && it.verificationCriteria.isNullOrBlank() }.sortedBy { it.id }.map { requirement -> val related = buildList { add(requirement.element.id) addAll(requirement.allocatedTo.map { it.id }) addAll(requirement.derivedFrom.map { it.id }) if (includeTestEvidence) { addAll( index.entities.filterIsInstance<TestCase>() .filter { requirement in it.verifies }.map { it.id }) } } review(index, requirement, relatedIds = related) } }

requirementApplicableStandardsConformance

Field

Description

Name

Requirement violates an applicable standard or interface

Contributor unknown

false

Default severity

MODERATE

Possible finding severities

INFO

Contract and evidence

A requirement shall conform to applicable government, industry, and product standards, specifications, and interfaces for which compliance is required.

Identify the applicable sources, versions, and relevant provisions/interfaces. Compare the requirement against those sources. A generic statement that it “complies with ISO 26262” is not evidence of conformance, and the absence of an available standard is not proof that no standard applies.

Corrective action

Identify the specific conflict and revise the requirement or obtain an authorized resolution of the applicable constraint. If the normative source is unavailable or applicability is unknown, report an open assessment.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.requirements.RequirementApplicableStandardsConformanceRule

Kotlin implementation

com.stigway.metamodels.create.requirements.RequirementApplicableStandardsConformanceRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/requirements/RequirementSemanticRules.kt:

class RequirementApplicableStandardsConformanceRule : RequirementSemanticRule() { override val name = "Requirement violates an applicable standard or interface" override val description = """ A requirement shall conform to applicable government, industry, and product standards, specifications, and interfaces for which compliance is required. Identify the applicable sources, versions, and relevant provisions/interfaces. Compare the requirement against those sources. A generic statement that it “complies with ISO 26262” is not evidence of conformance, and the absence of an available standard is not proof that no standard applies. """.trimIndent() override val remediation = """ Identify the specific conflict and revise the requirement or obtain an authorized resolution of the applicable constraint. If the normative source is unavailable or applicability is unknown, report an open assessment. """.trimIndent() }

com.stigway.metamodels.create.requirements.RequirementSemanticRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/requirements/RequirementSemanticRules.kt:

final override fun check(index: ModelIndex): List<ModelProblem> { if (index.subjectRequirements.isEmpty()) return noSubjects(index, "requirements") return index.subjectRequirements.filterNot { it.description.isNullOrBlank() || criteriaRequired && it.verificationCriteria.isNullOrBlank() }.sortedBy { it.id }.map { requirement -> val related = buildList { add(requirement.element.id) addAll(requirement.allocatedTo.map { it.id }) addAll(requirement.derivedFrom.map { it.id }) if (includeTestEvidence) { addAll( index.entities.filterIsInstance<TestCase>() .filter { requirement in it.verifies }.map { it.id }) } } review(index, requirement, relatedIds = related) } }

requirementWritingConventionConformance

Field

Description

Name

Requirement violates an approved writing convention

Contributor unknown

false

Default severity

MODERATE

Possible finding severities

INFO

Contract and evidence

A requirement shall conform to the applicable approved writing template and style conventions.

Reuse the existing CREATE attributes and executable language rules, then assess any additional identified project convention. Normative force and the choice of recognized modal must agree with the intended obligation and applicable writing conventions. An unidentified template remains missing evidence; do not invent one.

Corrective action

Bring the statement into the applicable convention without changing its engineering meaning, or identify a conflict between that convention and existing rule behavior for resolution at the rule's source.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.requirements.RequirementWritingConventionConformanceRule

Kotlin implementation

com.stigway.metamodels.create.requirements.RequirementWritingConventionConformanceRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/requirements/RequirementSemanticRules.kt:

class RequirementWritingConventionConformanceRule : RequirementSemanticRule() { override val name = "Requirement violates an approved writing convention" override val description = """ A requirement shall conform to the applicable approved writing template and style conventions. Reuse the existing CREATE attributes and executable language rules, then assess any additional identified project convention. Normative force and the choice of recognized modal must agree with the intended obligation and applicable writing conventions. An unidentified template remains missing evidence; do not invent one. """.trimIndent() override val remediation = """ Bring the statement into the applicable convention without changing its engineering meaning, or identify a conflict between that convention and existing rule behavior for resolution at the rule's source. """.trimIndent() }

com.stigway.metamodels.create.requirements.RequirementSemanticRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/requirements/RequirementSemanticRules.kt:

final override fun check(index: ModelIndex): List<ModelProblem> { if (index.subjectRequirements.isEmpty()) return noSubjects(index, "requirements") return index.subjectRequirements.filterNot { it.description.isNullOrBlank() || criteriaRequired && it.verificationCriteria.isNullOrBlank() }.sortedBy { it.id }.map { requirement -> val related = buildList { add(requirement.element.id) addAll(requirement.allocatedTo.map { it.id }) addAll(requirement.derivedFrom.map { it.id }) if (includeTestEvidence) { addAll( index.entities.filterIsInstance<TestCase>() .filter { requirement in it.verifies }.map { it.id }) } } review(index, requirement, relatedIds = related) } }

requirementCorrect

Field

Description

Name

Requirement misrepresents its source need

Contributor unknown

false

Default severity

MODERATE

Possible finding severities

INFO

Contract and evidence

A requirement shall accurately represent the entity need or parent obligation from which it was transformed.

Compare meaning with the identified source need, subject Context, and relevant parent requirements. A valid derivedFrom /allocation relationship proves a structural link, not semantic fidelity. A requirement whose subject element is marked isTopLevel need not have derivedFrom, but correctness still needs an identified need. The absence of a parent link at that boundary is not itself a correctness violation.

Corrective action

Correct the mistranslated obligation or the incorrect reference using the authoritative need. Record an open assessment when that need is unavailable instead of supplying a plausible substitute.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.requirements.RequirementCorrectRule

Kotlin implementation

com.stigway.metamodels.create.requirements.RequirementCorrectRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/requirements/RequirementSemanticRules.kt:

class RequirementCorrectRule : RequirementSemanticRule() { override val name = "Requirement misrepresents its source need" override val description = """ A requirement shall accurately represent the entity need or parent obligation from which it was transformed. Compare meaning with the identified source need, subject Context, and relevant parent requirements. A valid `derivedFrom`/allocation relationship proves a structural link, not semantic fidelity. A requirement whose subject element is marked `isTopLevel` need not have `derivedFrom`, but correctness still needs an identified need. The absence of a parent link at that boundary is not itself a correctness violation. """.trimIndent() override val remediation = """ Correct the mistranslated obligation or the incorrect reference using the authoritative need. Record an open assessment when that need is unavailable instead of supplying a plausible substitute. """.trimIndent() }

com.stigway.metamodels.create.requirements.RequirementSemanticRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/requirements/RequirementSemanticRules.kt:

final override fun check(index: ModelIndex): List<ModelProblem> { if (index.subjectRequirements.isEmpty()) return noSubjects(index, "requirements") return index.subjectRequirements.filterNot { it.description.isNullOrBlank() || criteriaRequired && it.verificationCriteria.isNullOrBlank() }.sortedBy { it.id }.map { requirement -> val related = buildList { add(requirement.element.id) addAll(requirement.allocatedTo.map { it.id }) addAll(requirement.derivedFrom.map { it.id }) if (includeTestEvidence) { addAll( index.entities.filterIsInstance<TestCase>() .filter { requirement in it.verifies }.map { it.id }) } } review(index, requirement, relatedIds = related) } }

requirementTimingConstraints

Field

Description

Name

Requirement omits necessary timing constraints

Contributor unknown

false

Default severity

MODERATE

Possible finding severities

INFO

Contract and evidence

Where correctness depends on execution, reaction, communication, or recurrence timing, a requirement shall state or unambiguously reference the necessary timing constraints and their relation to the required response.

Check the relevant trigger/reference event, response or period, units, limits, and any needed tolerance. A named FRTI_7 or cyclic_time3 is valid only when its definition and applicability are available. Do not require an invented deadline for a static property with no time-dependent obligation. Explain that non-applicability.

Corrective action

Obtain and state or reference the required timing budget and measurement points. “Immediately,” “quickly,” or an unexplained symbolic limit does not establish a measurable constraint. Do not guess a numerical value.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.requirements.RequirementTimingConstraintsRule

Kotlin implementation

com.stigway.metamodels.create.requirements.RequirementTimingConstraintsRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/requirements/RequirementSemanticRules.kt:

class RequirementTimingConstraintsRule : RequirementSemanticRule() { override val name = "Requirement omits necessary timing constraints" override val description = """ Where correctness depends on execution, reaction, communication, or recurrence timing, a requirement shall state or unambiguously reference the necessary timing constraints and their relation to the required response. Check the relevant trigger/reference event, response or period, units, limits, and any needed tolerance. A named `FRTI_7` or `cyclic_time3` is valid only when its definition and applicability are available. Do not require an invented deadline for a static property with no time-dependent obligation. Explain that non-applicability. """.trimIndent() override val remediation = """ Obtain and state or reference the required timing budget and measurement points. “Immediately,” “quickly,” or an unexplained symbolic limit does not establish a measurable constraint. Do not guess a numerical value. """.trimIndent() }

com.stigway.metamodels.create.requirements.RequirementSemanticRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/requirements/RequirementSemanticRules.kt:

final override fun check(index: ModelIndex): List<ModelProblem> { if (index.subjectRequirements.isEmpty()) return noSubjects(index, "requirements") return index.subjectRequirements.filterNot { it.description.isNullOrBlank() || criteriaRequired && it.verificationCriteria.isNullOrBlank() }.sortedBy { it.id }.map { requirement -> val related = buildList { add(requirement.element.id) addAll(requirement.allocatedTo.map { it.id }) addAll(requirement.derivedFrom.map { it.id }) if (includeTestEvidence) { addAll( index.entities.filterIsInstance<TestCase>() .filter { requirement in it.verifies }.map { it.id }) } } review(index, requirement, relatedIds = related) } }

requirementVerificationCriteriaAdequate

Field

Description

Name

Requirement lacks adequate acceptance criteria

Contributor unknown

false

Default severity

MODERATE

Possible finding severities

INFO

Contract and evidence

A requirement's verificationCriteria shall define an adequate qualitative or quantitative decision basis that distinguishes compliance from non-compliance with that requirement at its specified level.

Read verificationCriteria together with the requirement's obligation and precisely referenced definitions/evidence. A non-empty value passes only the executable presence check. Placeholder text, “test it,” or an unqualified “see description” does not establish adequate criteria.

Identify the relevant preconditions/stimulus, observable result, and necessary thresholds, bounds, units, timing, or tolerance. Criteria must agree with the requirement and be sufficient to make the acceptance decision. A precise reference can reuse an authoritative limit without duplicating the value in two attributes.

TestCase.verifies can locate supporting test evidence, but neither a link nor Given/When/Then structure supplies verificationCriteria or proves its adequacy. A test case need not exist yet. Test, analysis, inspection, and demonstration can all be verification methods; criteria are not execution results or approvals. Explicit “Pass”/“Fail” headings are optional when a precise predicate and its complement establish both.

Missing or blank verificationCriteria is checked by RequirementVerificationCriteriaDefinedRule. The adequacy review remains open until criteria are supplied; it must not invent a second semantic defect or substitute unrelated description text.

Corrective action

State the acceptance decision in verificationCriteria or make its authoritative reference precise. For an illustrative 100 ms response limit, identify the triggering event and required observable response: response within the bound passes; response after the bound or no response fails. Obtain the real project's values from its engineering evidence rather than inserting this example value.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.requirements.RequirementVerificationCriteriaAdequateRule

Kotlin implementation

com.stigway.metamodels.create.requirements.RequirementVerificationCriteriaAdequateRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/requirements/RequirementSemanticRules.kt:

class RequirementVerificationCriteriaAdequateRule : RequirementSemanticRule(criteriaRequired = true, includeTestEvidence = true) { override val name = "Requirement lacks adequate acceptance criteria" override val description = """ A requirement's `verificationCriteria` shall define an adequate qualitative or quantitative decision basis that distinguishes compliance from non-compliance with that requirement at its specified level. Read `verificationCriteria` together with the requirement's obligation and precisely referenced definitions/evidence. A non-empty value passes only the executable presence check. Placeholder text, “test it,” or an unqualified “see description” does not establish adequate criteria. Identify the relevant preconditions/stimulus, observable result, and necessary thresholds, bounds, units, timing, or tolerance. Criteria must agree with the requirement and be sufficient to make the acceptance decision. A precise reference can reuse an authoritative limit without duplicating the value in two attributes. `TestCase.verifies` can locate supporting test evidence, but neither a link nor Given/When/Then structure supplies `verificationCriteria` or proves its adequacy. A test case need not exist yet. Test, analysis, inspection, and demonstration can all be verification methods; criteria are not execution results or approvals. Explicit “Pass”/“Fail” headings are optional when a precise predicate and its complement establish both. Missing or blank `verificationCriteria` is checked by `RequirementVerificationCriteriaDefinedRule`. The adequacy review remains open until criteria are supplied; it must not invent a second semantic defect or substitute unrelated description text. """.trimIndent() override val remediation = """ State the acceptance decision in `verificationCriteria` or make its authoritative reference precise. For an illustrative 100 ms response limit, identify the triggering event and required observable response: response within the bound passes; response after the bound or no response fails. Obtain the real project's values from its engineering evidence rather than inserting this example value. """.trimIndent() }

com.stigway.metamodels.create.requirements.RequirementSemanticRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/requirements/RequirementSemanticRules.kt:

final override fun check(index: ModelIndex): List<ModelProblem> { if (index.subjectRequirements.isEmpty()) return noSubjects(index, "requirements") return index.subjectRequirements.filterNot { it.description.isNullOrBlank() || criteriaRequired && it.verificationCriteria.isNullOrBlank() }.sortedBy { it.id }.map { requirement -> val related = buildList { add(requirement.element.id) addAll(requirement.allocatedTo.map { it.id }) addAll(requirement.derivedFrom.map { it.id }) if (includeTestEvidence) { addAll( index.entities.filterIsInstance<TestCase>() .filter { requirement in it.verifies }.map { it.id }) } } review(index, requirement, relatedIds = related) } }

requirementSetNoInformationDuplication

Field

Description

Name

Requirements document duplicates obligations

Contributor unknown

false

Default severity

MODERATE

Possible finding severities

INFO

Contract and evidence

Within each assessed hierarchical level and applicability scope, the requirement set shall not redundantly restate the same obligation or authoritative information.

Compare meanings, subjects, conditions, and outcomes across the complete relevant set, including requirements in different containers. Equal names are allowed by the metamodel. Equal sentences about different elements are not necessarily duplicates; different sentences can duplicate the same obligation. Legitimate refinement between levels is not same-level duplication.

Corrective action

Identify the exact duplicated information, select or establish its authoritative definition, and consolidate or reference it while preserving allocation, derivation, and verification links. Do not delete one member of a suspected pair without understanding those dependencies.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.requirements.RequirementSetNoInformationDuplicationRule

Kotlin implementation

com.stigway.metamodels.create.requirements.RequirementSetNoInformationDuplicationRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/requirements/RequirementSemanticRules.kt:

class RequirementSetNoInformationDuplicationRule : RequirementSetSemanticRule() { override val name = "Requirements document duplicates obligations" override val description = """ Within each assessed hierarchical level and applicability scope, the requirement set shall not redundantly restate the same obligation or authoritative information. Compare meanings, subjects, conditions, and outcomes across the complete relevant set, including requirements in different containers. Equal names are allowed by the metamodel. Equal sentences about different elements are not necessarily duplicates; different sentences can duplicate the same obligation. Legitimate refinement between levels is not same-level duplication. """.trimIndent() override val remediation = """ Identify the exact duplicated information, select or establish its authoritative definition, and consolidate or reference it while preserving allocation, derivation, and verification links. Do not delete one member of a suspected pair without understanding those dependencies. """.trimIndent() }

com.stigway.metamodels.create.requirements.RequirementSetSemanticRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/requirements/RequirementSemanticRules.kt:

final override fun check(index: ModelIndex): List<ModelProblem> { val documents = index.subjectRequirements.mapNotNull { it.ownerContainer } .map(index::requirementsRoot).distinct().sortedBy { it.id } if (documents.isEmpty()) return noSubjects(index, "requirements documents") // A partial set must not be presented as a complete semantic comparison. if (index.requirements.any { it.description.isNullOrBlank() }) return emptyList() val comparisonIds = index.requirements.map { it.id }.sorted() return documents.map { document -> review( index, document, relatedIds = comparisonIds, subjectId = "requirement-set:${document.id}", scope = "requirements document ${document.idLabel} against the loaded requirement inventory", ) } }

requirementSetExternallyConsistent

Field

Description

Name

Requirements document contains conflicting obligations

Contributor unknown

false

Default severity

MODERATE

Possible finding severities

INFO

Contract and evidence

Requirements that apply together shall not conflict or impose incompatible overlapping obligations. Terminology and units shall be consistent within their defined domains. Safety and non-safety requirements that constrain the same behavior shall not contradict one another.

Assess conditions, including explicitly stated mode conditions, timing/order, shared interfaces, terminology, quantities, and measurement conventions across the relevant set. Opposite A-before-B and B-before-A obligations conflict when both apply to the same occurrences; different modes or events can make them compatible. Use dimensional compatibility and explicit conversions: equivalent values in milliseconds and seconds are not automatically a conflict.

Do not reduce set consistency to pairwise string comparison. Give the IDs of all requirements needed to demonstrate a conflict. Report duplicated information under the information uniqueness rule without repeating it as a consistency defect.

Corrective action

Resolve the identified conflict against authoritative needs and interfaces, and align the affected definitions or conventions. If priority or applicability is unresolved, state that missing decision explicitly.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.requirements.RequirementSetExternallyConsistentRule

Kotlin implementation

com.stigway.metamodels.create.requirements.RequirementSetExternallyConsistentRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/requirements/RequirementSemanticRules.kt:

class RequirementSetExternallyConsistentRule : RequirementSetSemanticRule() { override val name = "Requirements document contains conflicting obligations" override val description = """ Requirements that apply together shall not conflict or impose incompatible overlapping obligations. Terminology and units shall be consistent within their defined domains. Safety and non-safety requirements that constrain the same behavior shall not contradict one another. Assess conditions, including explicitly stated mode conditions, timing/order, shared interfaces, terminology, quantities, and measurement conventions across the relevant set. Opposite A-before-B and B-before-A obligations conflict when both apply to the same occurrences; different modes or events can make them compatible. Use dimensional compatibility and explicit conversions: equivalent values in milliseconds and seconds are not automatically a conflict. Do not reduce set consistency to pairwise string comparison. Give the IDs of all requirements needed to demonstrate a conflict. Report duplicated information under the information uniqueness rule without repeating it as a consistency defect. """.trimIndent() override val remediation = """ Resolve the identified conflict against authoritative needs and interfaces, and align the affected definitions or conventions. If priority or applicability is unresolved, state that missing decision explicitly. """.trimIndent() }

com.stigway.metamodels.create.requirements.RequirementSetSemanticRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/requirements/RequirementSemanticRules.kt:

final override fun check(index: ModelIndex): List<ModelProblem> { val documents = index.subjectRequirements.mapNotNull { it.ownerContainer } .map(index::requirementsRoot).distinct().sortedBy { it.id } if (documents.isEmpty()) return noSubjects(index, "requirements documents") // A partial set must not be presented as a complete semantic comparison. if (index.requirements.any { it.description.isNullOrBlank() }) return emptyList() val comparisonIds = index.requirements.map { it.id }.sorted() return documents.map { document -> review( index, document, relatedIds = comparisonIds, subjectId = "requirement-set:${document.id}", scope = "requirements document ${document.idLabel} against the loaded requirement inventory", ) } }

Design

designDescriptionActiveVoice

Field

Description

Name

Design description violates active present wording

Contributor unknown

false

Default severity

MODERATE

Possible finding severities

INFO

Contract and evidence

Authored descriptive prose shall use active voice and simple present wording. Normative requirement clauses retain the recognized obligation, prohibition, recommendation, or permission modal.

Apply this to applicable CREATE descriptions, including Requirement.description, TestCase.description, container descriptions, and notes. Preserve shall, shall not, should, should not, and may where they express the intended normative meaning. An active “Controller shall clear…” clause is valid; do not weaken it to “Controller clears…” merely to satisfy a tense heuristic. A copular state such as “flag is active” is not passive voice.

Preserve Given/When/Then structure in tests. Review narrative clauses, not code, formulas, identifiers, quoted standard text, or literal historical evidence as though they were sentences the agent may freely rewrite. Do not require every heading or table cell to contain a verb.

Corrective action

Name the actor and rewrite the relevant clause in active present/modal form without changing responsibility, timing, normative force, or the underlying engineering behavior. If the actor is unknown, identify the missing decision.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.DesignDescriptionActiveVoiceRule

Kotlin implementation

com.stigway.metamodels.create.DesignDescriptionActiveVoiceRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/DescriptionRules.kt:

class DesignDescriptionActiveVoiceRule : DescriptionActiveVoiceRule(Viewpoint.DESIGN) { override val name = "Design description violates active present wording" }

com.stigway.metamodels.create.DescriptionActiveVoiceRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/DescriptionRules.kt:

final override fun check(index: ModelIndex): List<ModelProblem> { val subjects = index.subjectEntities .filter { index.viewpoint(it) == viewpoint && it !is InterfacePointAnalysis } .sortedBy { it.id } if (subjects.isEmpty()) return noSubjects(index, "${viewpoint.name} description subjects") // Required-value rules own missing prose; wording can be reviewed once that prose exists. return subjects.filterNot { it.description.isNullOrBlank() }.map { entity -> review(index, entity) } }

Analysis

analysisDescriptionActiveVoice

Field

Description

Name

Analysis description violates active present wording

Contributor unknown

false

Default severity

MODERATE

Possible finding severities

INFO

Contract and evidence

Authored descriptive prose shall use active voice and simple present wording. Normative requirement clauses retain the recognized obligation, prohibition, recommendation, or permission modal.

Apply this to applicable CREATE descriptions, including Requirement.description, TestCase.description, container descriptions, and notes. Preserve shall, shall not, should, should not, and may where they express the intended normative meaning. An active “Controller shall clear…” clause is valid; do not weaken it to “Controller clears…” merely to satisfy a tense heuristic. A copular state such as “flag is active” is not passive voice.

Preserve Given/When/Then structure in tests. Review narrative clauses, not code, formulas, identifiers, quoted standard text, or literal historical evidence as though they were sentences the agent may freely rewrite. Do not require every heading or table cell to contain a verb.

Corrective action

Name the actor and rewrite the relevant clause in active present/modal form without changing responsibility, timing, normative force, or the underlying engineering behavior. If the actor is unknown, identify the missing decision.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.AnalysisDescriptionActiveVoiceRule

Kotlin implementation

com.stigway.metamodels.create.AnalysisDescriptionActiveVoiceRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/DescriptionRules.kt:

class AnalysisDescriptionActiveVoiceRule : DescriptionActiveVoiceRule(Viewpoint.ANALYSIS) { override val name = "Analysis description violates active present wording" }

com.stigway.metamodels.create.DescriptionActiveVoiceRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/DescriptionRules.kt:

final override fun check(index: ModelIndex): List<ModelProblem> { val subjects = index.subjectEntities .filter { index.viewpoint(it) == viewpoint && it !is InterfacePointAnalysis } .sortedBy { it.id } if (subjects.isEmpty()) return noSubjects(index, "${viewpoint.name} description subjects") // Required-value rules own missing prose; wording can be reviewed once that prose exists. return subjects.filterNot { it.description.isNullOrBlank() }.map { entity -> review(index, entity) } }

Tests

testsDescriptionActiveVoice

Field

Description

Name

Tests description violates active present wording

Contributor unknown

false

Default severity

MODERATE

Possible finding severities

INFO

Contract and evidence

Authored descriptive prose shall use active voice and simple present wording. Normative requirement clauses retain the recognized obligation, prohibition, recommendation, or permission modal.

Apply this to applicable CREATE descriptions, including Requirement.description, TestCase.description, container descriptions, and notes. Preserve shall, shall not, should, should not, and may where they express the intended normative meaning. An active “Controller shall clear…” clause is valid; do not weaken it to “Controller clears…” merely to satisfy a tense heuristic. A copular state such as “flag is active” is not passive voice.

Preserve Given/When/Then structure in tests. Review narrative clauses, not code, formulas, identifiers, quoted standard text, or literal historical evidence as though they were sentences the agent may freely rewrite. Do not require every heading or table cell to contain a verb.

Corrective action

Name the actor and rewrite the relevant clause in active present/modal form without changing responsibility, timing, normative force, or the underlying engineering behavior. If the actor is unknown, identify the missing decision.

Scope

Subjects from the checked module, with complete directly connected module content as evidence.

Kotlin declaration

com.stigway.metamodels.create.TestsDescriptionActiveVoiceRule

Kotlin implementation

com.stigway.metamodels.create.TestsDescriptionActiveVoiceRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/DescriptionRules.kt:

class TestsDescriptionActiveVoiceRule : DescriptionActiveVoiceRule(Viewpoint.TESTS) { override val name = "Tests description violates active present wording" }

com.stigway.metamodels.create.DescriptionActiveVoiceRule in stig-core/src/main/kotlin/com/stigway/metamodels/create/DescriptionRules.kt:

final override fun check(index: ModelIndex): List<ModelProblem> { val subjects = index.subjectEntities .filter { index.viewpoint(it) == viewpoint && it !is InterfacePointAnalysis } .sortedBy { it.id } if (subjects.isEmpty()) return noSubjects(index, "${viewpoint.name} description subjects") // Required-value rules own missing prose; wording can be reviewed once that prose exists. return subjects.filterNot { it.description.isNullOrBlank() }.map { entity -> review(index, entity) } }
23 October 2026