Validation

Usage guide, with the full diagnostic-code table and the strict modes: Validation.

Model validation: dangling references, duplicate names, cycles.

validate walks a model and returns Diagnostic records. Name resolution is stdlib-aware: unless disabled (stdlib=False), references resolve against the vendored standard library as a fallback, so ScalarValues::Real – or a bare Real, without any import – validates silently while a misspelled Reall warns. Implied specializations are honored too: a plain action def implicitly specializes Actions::Action, so inherited names like start and done resolve in expressions. Unresolved references are warnings; structural problems (duplicate names, specialization cycles, transitions to unknown states) are errors. strict=True promotes the resolution-failure family (RESOLUTION_CODES) to errors and additionally warns on import without a visibility prefix (bare-import) – see the design’s ratified open questions 1 and 4 (docs/design/conformance.md).

The dimensional lint (design: docs/design/units.md) also lives here: unit annotations must resolve (unresolved-unit), arithmetic over attributes with known dimension vectors must agree (dimension-mismatch – the mass + flightTime bug the interpreter silently evaluates), mixed measurement scales under +/- are an error (scale-mismatch: dBW + W, °C + K), same-dimension operands in different units warn without the [units] extra (mixed-units), and scoreboard ramp/target anchors are checked against their requirement’s measure (anchor-dimension-mismatch). Dimensions come from longeron.units, derived from the vendored library’s own definitional algebra; unknown dimensions are bottom and propagate silently – the lint only speaks when two known vectors conflict.

Flow connectivity gets the same treatment: a flow / message end that does not resolve warns (dangling-flow, the moral twin of dangling-expose), and a declared payload typing with no specialization relationship to the target end’s declared typing warns (flow-payload-mismatch). Typing absent on either side stays silent – the check only speaks when two known typings conflict.

The kind-level well-formedness checks (usage-type, attribute-composite-feature, redefinition-featuring-types, and friends – the full table lives in docs/guides/validation.md) apply the same contract to the SysML v2 metamodel’s clause-8.3 constraints: they only speak when a reference resolves and the resolved element’s kind is known to conflict. Unresolved references stay warnings, kinds outside the vocabulary families below (‘extended’ definitions, bare feature/ref usages) are bottom, and a resolved-but-wrong-kind target – a part typed by an attribute definition, a variant outside a variation, two subjects in one requirement – is a structural self-contradiction and therefore an error.

longeron.validation.RESOLUTION_CODES = frozenset({'dangling-expose', 'dangling-flow', 'dangling-succession', 'unresolved-name', 'unresolved-reference', 'unresolved-unit'})

the resolution-failure family: every warning code that reports a reference which failed to resolve. validate(strict=True) promotes exactly these to error severity – and nothing else. Codes that fire on successful resolution (stdlib-implicit-name) or on conflicts between resolved typings (flow-payload-mismatch, the dimensional lint) are not resolution failures and keep their severity.

class longeron.validation.Diagnostic(severity, code, message, element, location=None)[source]

Bases: object

longeron.validation.validate(model, *, stdlib=None, strict_imports=False, strict=False, evidence_coverage=False)[source]

Validate a model; returns diagnostics sorted errors-first.

strict promotes the resolution-failure warnings (RESOLUTION_CODES: unresolved-reference, unresolved-name, unresolved-unit, dangling-expose, dangling-flow, dangling-succession) to error severity, and additionally warns (bare-import) on an import with no visibility prefix – the spec BNF requires one; longeron’s default mode deliberately accepts the bare form because the OMG corpus writes it (grammar patch 1). No other diagnostic changes severity under strict.

stdlib controls the standard-library fallback used for name resolution: None (default) auto-attaches the vendored library when it loads, True forces it, False disables it. The library is only consulted by the resolver – model is never mutated.

strict_imports additionally warns (stdlib-implicit-name) for bare standard-library names that resolve only through the implicit library-visibility hop – the KerML global-namespace convenience for standard library packages. Qualified names (ScalarValues::Real) and explicitly imported names stay silent.

evidence_coverage opts into the coverage lint of longeron.evidence (unevidenced-value): a warning per stated attribute value that carries no SourceEvidence citation. Off by default – most models legitimately carry derived and assumed values, so absence is a report, not a defect (the provenance design’s ratified posture). evidence-drift needs no flag: when the model carries citations, each one that verifies as drifted or quote-lost warns. Verification never touches the network here – URL documents check against the local evidence cache only.

Elements inside library packages are never the subject of diagnostics: a merged-in standard library (e.g. via the CLI’s --stdlib) is resolution context, not the model under validation.

Return type:

list[Diagnostic]