MATLAB Requirements Toolbox — Requirements & Traceability
This skill covers everything in the slreq API: creating and reading requirements,
managing traceability links, checking verification coverage, allocating requirements
to architecture components, and auditing link health.
For architecture phases (System Composer models, functional decomposition,
functional→physical allocation) see the mbse-architecture skill.
See references/api-quickref.md in this skill folder for a compact one-page API reference.
The Two File Types
| Extension | Class | Role |
|---|---|---|
.slreqx | slreq.ReqSet | Stores requirements (text, hierarchy) |
.slmx | slreq.LinkSet | Stores traceability links outgoing from a source artifact |
When a .slmx file is created
slreq writes a .slmx file only when its companion artifact is the source of at least one link. The LinkSet is keyed on the source artifact, not the destination.
MyReqs~slreqx.slmxappears only if some link's source is a requirement inMyReqs.slreqx(e.g.,slreq.createLink(srcReq, destReq)wheresrcReqlives inMyReqs)MyModel~mdl.slmxappears only if some link's source is a model element inMyModel.slx(typical:slreq.createLink(component, req)with TypeImplement— the component is the source)
An artifact that is only ever a link destination never gets a paired .slmx. In a typical MBSE project:
| Artifact | Gets a .slmx? | Why |
|---|---|---|
StakeholderNeeds.slreqx | Yes | SNs are the source of Derive links to SRs |
SystemRequirements.slreqx | Usually no | SRs are destinations of Derive / Implement / Verify links; no file unless SR-to-SR Refine links or links to external docs are added |
TestCases.slreqx | Yes | TC requirements are the source of Verify links to SRs |
Architecture .slx models | Yes | Components are the source of Implement links to SRs |
Reporting rules for build scripts
Because .slmx files are conditional, never claim a .slmx was produced based on the API calls you made — always verify with isfile before reporting. A script that creates only SN→SR Derive links will produce StakeholderNeeds~slreqx.slmx but not SystemRequirements~slreqx.slmx, even though both .slreqx files exist.
Idempotent cleanup and project registration for .slmx files must both guard with isfile:
if isfile(snLinks), delete(snLinks); end % cleanup — safe whether or not it exists
The registerWithProject helper already does this — it skips files that don't exist on disk — so passing a non-existent .slmx path is a no-op, not an error.
Requirements (Phases 1–2)
Two-Level Structure
| Level | ID scheme | Character |
|---|---|---|
| Stakeholder Needs | SN-SYS-001 | Operational, informal — what the user/operator needs |
| System Requirements | SR-SYS-001 | Formal, testable — what the system shall do |
Each SR traces back to one or more SNs via a Derive link.
Well-Formed Shall-Statements
- One obligation per requirement ("shall", not "should" or "will")
- Measurable and testable — include numeric criteria where possible
- Avoid
<and>in Description fields — the Requirements Editor treats them as HTML. Use "not exceeding", "at least", "greater than", etc.
Good: The system shall respond with latency not exceeding 100 ms.
Avoid: The system shall respond with latency < 100 ms.
Creating Requirement Sets
slreq.clear();
if isfile('MyReqs.slreqx'), delete('MyReqs.slreqx'); end
rs = slreq.new('MyReqs.slreqx'); % NOT slreq.createReqSet (does not exist)
req = rs.add();
req.Id = 'SR-SYS-001';
req.Summary = 'Short title';
req.Description = 'The system shall ...';
req.Rationale = 'Why this requirement exists.';
rs.save();
Find a requirement by ID
req = rs.find('Id', 'SR-SYS-001');
Valid Link Types
| Type | Meaning | Direction |
|---|---|---|
"Derive" | Parent decomposes into derived child | SN (source) → SR (destination) |
"Implement" | Architecture element (or model block) implements requirement | Component/Block (source) → SR (destination) |
"Verify" | Test case verifies requirement | TC (source) → SR (destination) |
"Refine" | Requirement refined into a more specific requirement (same artifact kind, more detail). Not used for SR → architecture in this workflow. | SR (source) → SR (destination) |
"Relate" | Informal relationship | Bidirectional |
Creating Links
% Req-to-req derivation: parent (e.g. SN) decomposes into derived child (e.g. SR)
lnk = slreq.createLink(parentReq, childReq);
lnk.Type = 'Derive';
% Model block to req (model must be open in Simulink)
lnk = slreq.createLink(blockHandle, req);
lnk.Type = 'Implement';
% Test case requirement to SR
lnk = slreq.createLink(tc, sr);
lnk.Type = 'Verify';
slreq.saveAll(); % always call after creating cross-artifact links
Side effect: {modelName}~mdl.slmx link store
The first time you create a link whose source is an element of a Simulink/System Composer
model (component, subsystem, or block), slreq writes a {modelName}~mdl.slmx file next to the
.slx. This is the normal case for Implement links in this workflow — slreq.createLink(component, req)
has the component as source, so the link lives in the model's LinkSet, not the requirement set's.
A model that only ever receives links (no element of it is used as a link source) does not
get a ~mdl.slmx. In MBSE practice this is rare: architecture models almost always have Implement
links where they are the source.
After creating links whose source is in a model, register both the .slx and the .slmx with the
project, guarding .slmx registration with isfile since the file may not yet exist:
addFile(proj, fullfile(archDir, 'MyModel.slx'));
slmx = fullfile(archDir, 'MyModel~mdl.slmx');
if isfile(slmx), addFile(proj, slmx); end
Forgetting to register an existing .slmx causes project file-system checks to fail and the
traceability links won't travel when the project is shared.
Requirements Script Skeleton
See code/buildMyRequirements.m for the full parameterized function:
buildMyRequirements(snFile, srFile)
Exporting a Requirement Set to Excel
There is no public slreq Excel-export API. slreq.export emits ReqIF only,
and the Requirements Editor's File → Export → Microsoft Excel is GUI-only. To
script an xlsx export, build the table yourself with writetable.
Requirement sets can be hierarchical. find(rs, 'Type', 'Requirement')
returns all requirements flat in storage order, which silently drops the
parent/child structure the Requirements Editor displays. To preserve hierarchy:
- Find top-level reqs by filtering for
~isa(r.parent(), 'slreq.Requirement')— top-level items have the ReqSet as their parent, not another requirement - Recurse via the
children()method (a method, not a property) - Emit rows depth-first so each parent precedes its children
- Sort siblings with a natural sort on the
Indexstring ("1", "1.2", "1.10" as numeric tuples — lexicographic string sort would put 1.10 before 1.2) - Write
Index,Depth,ParentIndexcolumns so the hierarchy is recoverable from the xlsx alone
Note also that r.Id may be an auto-assigned SID like #13 if the set was
authored in the Editor without user IDs — always include the Index column as
a stable user-meaningful identifier.
Extract parent IDs from incoming Derive links so the DerivedFrom column is
populated instead of stuffing parent refs into Rationale:
function ids = deriveParents(req)
ids = strings(0,1);
lnks = req.inLinks();
for k = 1:numel(lnks)
if strcmp(lnks(k).Type, 'Derive')
% getSourceLabel() returns "ID Summary"; strtok pulls just the ID
ids(end+1,1) = string(strtok(