Skip to content

Traceability

The queries in sysml2kit.query answer the questions a requirements-driven workflow actually asks:

Question Call
What satisfies this requirement? satisfied_by(model, req)
What verifies it? verified_by(model, req)
What does it derive from? derived_from(model, req)
Which requirements have no satisfier? unsatisfied_requirements(model)
Which have no verifier? unverified_requirements(model)
What is allocated where? allocation_table(model)
The whole grid at once? trace_matrix(model).render()

The four relationship kinds are first-class elements (SatisfyRelationship, VerifyRelationship, DeriveRelationship, AllocateRelationship) created through the builder:

builder.satisfy(model, source=battery, target=mass_req)
builder.verify(model, source=range_analysis, target=range_req)
builder.derive(model, source=mass_req, target=range_req)
builder.allocate(model, source=range_req, target=battery)

Handing requirements to an engine: the metricKey convention

A requirement usage that owns attributes metricKey (string), threshold (number with unit), op (>=, <=, ==, >, <), and optionally severity (must/should/nice) is machine-checkable. sysml2kit.interop.extract_requirements turns each into a RequirementSpec carrying the threshold in both operator form (op + value) and bound form (minimum/maximum), plus the satisfy/verify trace as qualified names:

from sysml2kit.interop import extract_requirements

for spec in extract_requirements(model):
    print(spec.id, spec.metric_key, spec.op, spec.value, spec.satisfied_by)

Both forms are always populated (>= 40 also sets minimum=40), so an operator-style requirements engine (phased-array-systems) and a bound-style one (aedl) each need only a small adapter, which lives in those packages. The metric key names the entry in the engine's metrics dict; the model never computes anything itself.