265 lines
6.8 KiB
Markdown
265 lines
6.8 KiB
Markdown
---
|
|
name: 'step-04e-aggregate-nfr'
|
|
description: 'Aggregate NFR domain assessments into executive summary'
|
|
nextStepFile: './step-05-generate-report.md'
|
|
outputFile: '{test_artifacts}/nfr-assessment.md'
|
|
---
|
|
|
|
# Step 4E: Aggregate NFR Assessment Results
|
|
|
|
## STEP GOAL
|
|
|
|
Read outputs from 4 parallel NFR subagents, calculate overall risk level, aggregate compliance status, and identify cross-domain risks.
|
|
|
|
---
|
|
|
|
## MANDATORY EXECUTION RULES
|
|
|
|
- 📖 Read the entire step file before acting
|
|
- ✅ Speak in `{communication_language}`
|
|
- ✅ Read all 4 subagent outputs
|
|
- ✅ Calculate overall risk level
|
|
- ❌ Do NOT re-assess NFRs (use subagent outputs)
|
|
|
|
---
|
|
|
|
## MANDATORY SEQUENCE
|
|
|
|
### 1. Read All Subagent Outputs
|
|
|
|
```javascript
|
|
const domains = ['security', 'performance', 'reliability', 'scalability'];
|
|
const assessments = {};
|
|
|
|
domains.forEach((domain) => {
|
|
const outputPath = `/tmp/tea-nfr-${domain}-{{timestamp}}.json`;
|
|
assessments[domain] = JSON.parse(fs.readFileSync(outputPath, 'utf8'));
|
|
});
|
|
```
|
|
|
|
---
|
|
|
|
### 2. Calculate Overall Risk Level
|
|
|
|
**Risk hierarchy:** HIGH > MEDIUM > LOW > NONE
|
|
|
|
```javascript
|
|
const riskLevels = { HIGH: 3, MEDIUM: 2, LOW: 1, NONE: 0 };
|
|
const domainRisks = domains.map((d) => assessments[d].risk_level);
|
|
const maxRiskValue = Math.max(...domainRisks.map((r) => riskLevels[r]));
|
|
const overallRisk = Object.keys(riskLevels).find((k) => riskLevels[k] === maxRiskValue);
|
|
```
|
|
|
|
**Risk assessment:**
|
|
|
|
- If ANY domain is HIGH → overall is HIGH
|
|
- If ANY domain is MEDIUM (and none HIGH) → overall is MEDIUM
|
|
- If ALL domains are LOW/NONE → overall is LOW
|
|
|
|
---
|
|
|
|
### 3. Aggregate Compliance Status
|
|
|
|
```javascript
|
|
const allCompliance = {};
|
|
|
|
domains.forEach((domain) => {
|
|
const compliance = assessments[domain].compliance;
|
|
Object.entries(compliance).forEach(([standard, status]) => {
|
|
if (!allCompliance[standard]) {
|
|
allCompliance[standard] = [];
|
|
}
|
|
allCompliance[standard].push({ domain, status });
|
|
});
|
|
});
|
|
|
|
// Determine overall compliance per standard
|
|
const complianceSummary = {};
|
|
Object.entries(allCompliance).forEach(([standard, statuses]) => {
|
|
const hasFail = statuses.some((s) => s.status === 'FAIL');
|
|
const hasPartial = statuses.some((s) => s.status === 'PARTIAL' || s.status === 'CONCERN');
|
|
|
|
complianceSummary[standard] = hasFail ? 'FAIL' : hasPartial ? 'PARTIAL' : 'PASS';
|
|
});
|
|
```
|
|
|
|
---
|
|
|
|
### 4. Identify Cross-Domain Risks
|
|
|
|
**Look for risks that span multiple domains:**
|
|
|
|
```javascript
|
|
const crossDomainRisks = [];
|
|
|
|
// Example: Performance + Scalability issue
|
|
const perfConcerns = assessments.performance.findings.filter((f) => f.status !== 'PASS');
|
|
const scaleConcerns = assessments.scalability.findings.filter((f) => f.status !== 'PASS');
|
|
if (perfConcerns.length > 0 && scaleConcerns.length > 0) {
|
|
crossDomainRisks.push({
|
|
domains: ['performance', 'scalability'],
|
|
description: 'Performance issues may worsen under scale',
|
|
impact: 'HIGH',
|
|
});
|
|
}
|
|
|
|
// Example: Security + Reliability issue
|
|
const securityFails = assessments.security.findings.filter((f) => f.status === 'FAIL');
|
|
const reliabilityConcerns = assessments.reliability.findings.filter((f) => f.status !== 'PASS');
|
|
if (securityFails.length > 0 && reliabilityConcerns.length > 0) {
|
|
crossDomainRisks.push({
|
|
domains: ['security', 'reliability'],
|
|
description: 'Security vulnerabilities may cause reliability incidents',
|
|
impact: 'CRITICAL',
|
|
});
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### 5. Aggregate Priority Actions
|
|
|
|
```javascript
|
|
const allPriorityActions = domains.flatMap((domain) =>
|
|
assessments[domain].priority_actions.map((action) => ({
|
|
domain,
|
|
action,
|
|
urgency: assessments[domain].risk_level === 'HIGH' ? 'URGENT' : 'NORMAL',
|
|
})),
|
|
);
|
|
|
|
// Sort by urgency
|
|
const prioritizedActions = allPriorityActions.sort((a, b) => (a.urgency === 'URGENT' ? -1 : 1));
|
|
```
|
|
|
|
---
|
|
|
|
### 6. Generate Executive Summary
|
|
|
|
```javascript
|
|
const resolvedMode = subagentContext?.execution?.resolvedMode ?? 'unknown';
|
|
const subagentExecutionLabel =
|
|
resolvedMode === 'sequential'
|
|
? 'SEQUENTIAL (4 NFR domains)'
|
|
: resolvedMode === 'agent-team'
|
|
? 'AGENT-TEAM (4 NFR domains)'
|
|
: resolvedMode === 'subagent'
|
|
? 'SUBAGENT (4 NFR domains)'
|
|
: 'MODE-DEPENDENT (4 NFR domains)';
|
|
|
|
const performanceGainLabel =
|
|
resolvedMode === 'sequential'
|
|
? 'baseline (no parallel speedup)'
|
|
: resolvedMode === 'agent-team' || resolvedMode === 'subagent'
|
|
? '~67% faster than sequential'
|
|
: 'mode-dependent';
|
|
|
|
const executiveSummary = {
|
|
overall_risk: overallRisk,
|
|
assessment_date: new Date().toISOString(),
|
|
|
|
domain_assessments: assessments,
|
|
|
|
compliance_summary: complianceSummary,
|
|
|
|
cross_domain_risks: crossDomainRisks,
|
|
|
|
priority_actions: prioritizedActions,
|
|
|
|
risk_breakdown: {
|
|
security: assessments.security.risk_level,
|
|
performance: assessments.performance.risk_level,
|
|
reliability: assessments.reliability.risk_level,
|
|
scalability: assessments.scalability.risk_level,
|
|
},
|
|
|
|
subagent_execution: subagentExecutionLabel,
|
|
performance_gain: performanceGainLabel,
|
|
};
|
|
|
|
// Save for Step 5 (report generation)
|
|
fs.writeFileSync('/tmp/tea-nfr-summary-{{timestamp}}.json', JSON.stringify(executiveSummary, null, 2), 'utf8');
|
|
```
|
|
|
|
---
|
|
|
|
### 7. Display Summary to User
|
|
|
|
```
|
|
✅ NFR Assessment Complete ({subagentExecutionLabel})
|
|
|
|
🎯 Overall Risk Level: {overallRisk}
|
|
|
|
📊 Domain Risk Breakdown:
|
|
- Security: {security_risk}
|
|
- Performance: {performance_risk}
|
|
- Reliability: {reliability_risk}
|
|
- Scalability: {scalability_risk}
|
|
|
|
✅ Compliance Summary:
|
|
{list standards with PASS/PARTIAL/FAIL}
|
|
|
|
⚠️ Cross-Domain Risks: {cross_domain_risk_count}
|
|
|
|
🎯 Priority Actions: {priority_action_count}
|
|
|
|
🚀 Performance: {performanceGainLabel}
|
|
|
|
✅ Ready for report generation (Step 5)
|
|
```
|
|
|
|
---
|
|
|
|
---
|
|
|
|
### 8. Save Progress
|
|
|
|
**Save this step's accumulated work to `{outputFile}`.**
|
|
|
|
- **If `{outputFile}` does not exist** (first save), create it using the workflow template (if available) with YAML frontmatter:
|
|
|
|
```yaml
|
|
---
|
|
stepsCompleted: ['step-04e-aggregate-nfr']
|
|
lastStep: 'step-04e-aggregate-nfr'
|
|
lastSaved: '{date}'
|
|
---
|
|
```
|
|
|
|
Then write this step's output below the frontmatter.
|
|
|
|
- **If `{outputFile}` already exists**, update:
|
|
- Add `'step-04e-aggregate-nfr'` to `stepsCompleted` array (only if not already present)
|
|
- Set `lastStep: 'step-04e-aggregate-nfr'`
|
|
- Set `lastSaved: '{date}'`
|
|
- Append this step's output to the appropriate section of the document.
|
|
|
|
---
|
|
|
|
## EXIT CONDITION
|
|
|
|
Proceed to Step 5 when:
|
|
|
|
- ✅ All subagent outputs read
|
|
- ✅ Overall risk calculated
|
|
- ✅ Compliance aggregated
|
|
- ✅ Summary saved
|
|
- ✅ Progress saved to output document
|
|
|
|
Load next step: `{nextStepFile}`
|
|
|
|
---
|
|
|
|
## 🚨 SYSTEM SUCCESS METRICS
|
|
|
|
### ✅ SUCCESS:
|
|
|
|
- All 4 NFR domains aggregated correctly
|
|
- Overall risk level determined
|
|
- Executive summary complete
|
|
|
|
### ❌ FAILURE:
|
|
|
|
- Failed to read subagent outputs
|
|
- Risk calculation incorrect
|