-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmakeVariantTraceMatrix.m
More file actions
158 lines (146 loc) · 7.33 KB
/
Copy pathmakeVariantTraceMatrix.m
File metadata and controls
158 lines (146 loc) · 7.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
function makeVariantTraceMatrix()
%MAKEVARIANTTRACEMATRIX Per-variant requirements trace documents (ADR-035).
% Generates docs/deliverables/variantRequirementsTraces.md (one trace
% section per candidate architecture plus a side-by-side comparison
% matrix) and variantRequirementsTraces.csv (the same data long-form),
% the design-review evidence that shows implementation and verification
% separately for HyperCook, LeanBroth, and EverSimmer.
%
% Requirements Toolbox cannot produce this view natively: link sets
% auto-load with the requirement set and cannot be selectively
% unloaded, so slreq status columns and slreq.generateReport always
% aggregate all three mutually exclusive candidates. This generator
% attributes status instead: Implement links by source artifact,
% Verify links by the variant the test case simulates (case names
% lead with the variant), gate verdicts from the per-variant formal
% gate results (analysis/results/complianceGate.csv), and the known
% non-compliances from the same regression-baseline findings the test
% suite pins (literals below, maintained with the suite).
%
% Run after a green runAllTests: "verified" cells assume the latest
% full-suite run passed (runAllTests asserts exactly the per-variant
% verified-SR sets this generator reports).
proj = currentProject;
outMd = char(fullfile(proj.RootFolder, 'docs', 'deliverables', 'variantRequirementsTraces.md'));
outCsv = char(fullfile(proj.RootFolder, 'docs', 'deliverables', 'variantRequirementsTraces.csv'));
variants = {'HyperCook','LeanBroth','EverSimmer'};
% formal gate rows -> the SR each row refines (buildComplianceGate)
gateSR = containers.Map( ...
{'Mass','Power','Cost','Volume','Throughput','Automation','Operators','Gravity'}, ...
{'SR-GS-011','SR-GS-012','SR-GS-013','SR-GS-014','SR-GS-002','SR-GS-003','SR-GS-004','SR-GS-015'});
gate = readtable(fullfile(char(proj.RootFolder),'analysis','results','complianceGate.csv'), ...
'ReadRowNames', true);
% known non-compliances demonstrated by unlinked regression-baseline
% cases (same literals the suite asserts; see buildSystemTestFile)
findings = { ...
'HyperCook', 'SR-GS-026', 'FAILS - single-string collapse, 0% retention ("HyperCook worst fault - regression baseline")'; ...
'LeanBroth', 'SR-GS-002', 'FAILS - 196.8 bph vs 200 floor ("LeanBroth nominal - regression baseline")'; ...
'LeanBroth', 'SR-GS-018', 'FAILS - 1241.5 s vs 1200 s limit ("LeanBroth rocket turnaround - regression baseline")'; ...
'LeanBroth', 'SR-GS-026', 'FAILS - single-string collapse, 0% retention ("LeanBroth worst fault - regression baseline")'; ...
'EverSimmer', 'SR-GS-015', 'FAILS at 0.1 g - 189.3 bph vs 200 floor ("EverSimmer at 0.1 g - regression baseline"; ADR-026)'};
slreq.clear();
srSet = slreq.load(fullfile(char(proj.RootFolder),'requirements','SystemRequirements.slreqx'));
reqs = find(srSet, 'Type', 'Requirement');
% Verify links per variant: case names lead with the variant
tfile = sltest.testmanager.load(fullfile(char(proj.RootFolder), ...
'tests','system','GalacticSoupSystemTests.mldatx'));
verCase = containers.Map(); % '<variant>|<SR>' -> case name(s)
for s = getTestSuites(tfile)
for tc = getTestCases(s)
vIdx = find(cellfun(@(p) startsWith(tc.Name, p), variants), 1);
for L = slreq.outLinks(tc)
key = sprintf('%s|%s', variants{vIdx}, char(destination(L).id));
if isKey(verCase, key)
verCase(key) = sprintf('%s; "%s"', verCase(key), tc.Name);
else
verCase(key) = sprintf('"%s"', tc.Name);
end
end
end
end
fid = fopen(outMd, 'wt');
closeMd = onCleanup(@() fclose(fid));
fprintf(fid, '# Per-Variant Requirements Traces\n\n');
fprintf(fid, ['Generated by `analysis/reporting/makeVariantTraceMatrix.m` after a green `runAllTests` ' ...
'- do not hand-edit. One trace per candidate physical architecture (no baseline is committed; ' ...
'ADR-035), then a side-by-side comparison. Implemented = Implement links from the variant model ' ...
'(direct) and/or the variant-independent functional architecture. Gate = the variant''s verdict ' ...
'from the formal Requirements Table gate. Test evidence = Verify-linked simulation cases ' ...
'(verified) or the pinned regression-baseline finding (FAILS).\n\n']);
csvRows = cell(0, 7);
verdict = containers.Map(); % '<variant>|<SR>' -> compact comparison verdict
for v = 1:numel(variants)
vn = variants{v};
fprintf(fid, '## %s\n\n', vn);
fprintf(fid, '| SR | Requirement | Implemented | Gate | Test evidence |\n');
fprintf(fid, '|---|---|---|---|---|\n');
for r = reqs
id = char(r.Id);
direct = false; shared = false;
for L = inLinks(r)
try
if strcmp(L.Type,'Implement')
art = char(source(L).artifact);
direct = direct || contains(art, ['Physical' vn]);
shared = shared || contains(art, 'Functional');
end
catch
end
end
if direct && shared, impl = 'direct + functional';
elseif direct, impl = 'direct';
elseif shared, impl = 'functional';
else, impl = '-';
end
gv = '-';
for gk = keys(gateSR)
if strcmp(gateSR(gk{1}), id)
if gate{vn, gk{1}} == 1, gv = 'PASS'; else, gv = 'FAIL'; end
end
end
key = sprintf('%s|%s', vn, id);
fRow = strcmp(findings(:,1), vn) & strcmp(findings(:,2), id);
if isKey(verCase, key)
ev = sprintf('verified: %s', verCase(key));
verdict(key) = 'verified';
elseif any(fRow)
ev = findings{fRow, 3};
verdict(key) = 'FAILS';
elseif strcmp(gv, 'FAIL')
ev = 'no test case; formal gate FAILS';
verdict(key) = 'FAILS';
elseif strcmp(gv, 'PASS')
ev = '-';
verdict(key) = 'gate PASS';
else
ev = '-';
verdict(key) = '-';
end
fprintf(fid, '| %s | %s | %s | %s | %s |\n', id, char(r.Summary), impl, gv, ev);
csvRows(end+1,:) = {id, char(r.Summary), vn, impl, gv, ...
regexprep(ev, '^verified: ', ''), verdict(key)}; %#ok<AGROW>
end
fprintf(fid, '\n');
end
fprintf(fid, '## Comparison\n\n');
fprintf(fid, ['verified = Verify-linked simulation case passed for that variant; FAILS = pinned ' ...
'finding or formal gate failure; gate PASS = formal gate evidence only; - = no ' ...
'variant-specific evidence (analysis-chain coverage may still apply).\n\n']);
fprintf(fid, '| SR | Requirement | HyperCook | LeanBroth | EverSimmer |\n');
fprintf(fid, '|---|---|---|---|---|\n');
for r = reqs
id = char(r.Id);
cells = cellfun(@(vn) verdict(sprintf('%s|%s', vn, id)), variants, 'UniformOutput', false);
fprintf(fid, '| %s | %s | %s | %s | %s |\n', id, char(r.Summary), cells{:});
end
clear closeMd
T = cell2table(csvRows, 'VariableNames', ...
{'SR','Requirement','Variant','Implemented','Gate','TestEvidence','Verdict'});
writetable(T, outCsv);
pf = {proj.Files.Path};
for f = {outMd, outCsv}
if ~any(strcmpi(pf, f{1})), addFile(proj, f{1}); end
addLabel(findFile(proj, f{1}), 'Classification', 'Artifact');
end
fprintf('variant traces: %s (+.csv), %d SRs x %d variants\n', outMd, numel(reqs), numel(variants));
end