Analyzer Package
The @traceweave/trf-analyzer package provides graph analytics for .twpack files, including impact analysis, coverage metrics, and path finding.
Installation
npm install @traceweave/trf-analyzer
Quick Start
const { TwpackAnalyzer } = require('@traceweave/trf-analyzer');
const analyzer = new TwpackAnalyzer();
await analyzer.loadTwpack('./my-pack.twpack');
// Get statistics
const stats = analyzer.getStats();
console.log(`Total artifacts: ${stats.totalArtifacts}`);
console.log(`Total links: ${stats.totalLinks}`);
// Impact analysis
const impact = analyzer.impactAnalysis('req:REQ-001');
console.log(`Impacted artifacts: ${impact.totalImpacted}`);
// Coverage analysis
const coverage = analyzer.coverageAnalysis('requirement');
console.log(`Coverage: ${coverage.coveragePercent}%`);
// Always close when done
analyzer.close();
API Reference
TwpackAnalyzer
loadTwpack(path)
Load a .twpack file for analysis.
await analyzer.loadTwpack('./my-pack.twpack');
getStats()
Get graph statistics.
const stats = analyzer.getStats();
Returns:
{
totalArtifacts: number;
totalLinks: number;
avgInDegree: number;
avgOutDegree: number;
isolatedArtifacts: number;
artifactsByKind: { [kind: string]: number };
linksByRelation: { [relation: string]: number };
}
impactAnalysis(artifactId)
Analyze downstream impact (forward graph traversal).
const impact = analyzer.impactAnalysis('req:REQ-001');
Returns:
{
artifactId: string;
totalImpacted: number;
impactedArtifacts: Array<{
id: string;
kind: string;
path: string[];
distance: number;
}>;
}
rootCauseAnalysis(artifactId)
Analyze dependencies (backward graph traversal).
const rootCause = analyzer.rootCauseAnalysis('test:TEST-001');
Returns:
{
artifactId: string;
totalDependencies: number;
dependencies: Array<{
id: string;
kind: string;
path: string[];
distance: number;
}>;
}
coverageAnalysis(kind, relation?)
Analyze traceability coverage for a specific artifact kind.
// All coverage for requirements
const coverage = analyzer.coverageAnalysis('requirement');
// Coverage for specific relation
const verifiedCoverage = analyzer.coverageAnalysis('requirement', 'verified_by');
Returns:
{
kind: string;
relation?: string;
total: number;
covered: number;
uncovered: number;
coveragePercent: number;
uncoveredArtifacts: string[];
}
findPaths(fromId, toId)
Find all paths between two artifacts.
const paths = analyzer.findPaths('req:REQ-001', 'test:TEST-005');
Returns:
{
from: string;
to: string;
pathCount: number;
paths: Array<{
artifacts: string[];
length: number;
}>;
}
close()
Close the analyzer and cleanup resources.
analyzer.close();
Important: Always call close() when done to release database connections.
Complete Example
const { TwpackAnalyzer } = require('@traceweave/trf-analyzer');
async function analyzeCompliance() {
const analyzer = new TwpackAnalyzer();
try {
// Load pack
await analyzer.loadTwpack('./automotive-iso26262.twpack');
// 1. Get overall statistics
const stats = analyzer.getStats();
console.log('📊 Statistics:');
console.log(` Total artifacts: ${stats.totalArtifacts}`);
console.log(` Total links: ${stats.totalLinks}`);
console.log(` Requirements: ${stats.artifactsByKind.requirement || 0}`);
console.log(` Tests: ${stats.artifactsByKind.test || 0}`);
// 2. Check coverage for all requirements
const reqCoverage = analyzer.coverageAnalysis('requirement', 'verified_by');
console.log(`\n📈 Requirement Coverage: ${reqCoverage.coveragePercent}%`);
console.log(` Covered: ${reqCoverage.covered}/${reqCoverage.total}`);
if (reqCoverage.uncoveredArtifacts.length > 0) {
console.log(' Uncovered requirements:');
reqCoverage.uncoveredArtifacts.forEach(id => {
console.log(` - ${id}`);
});
}
// 3. Impact analysis for critical requirement
const impact = analyzer.impactAnalysis('req:SAFETY-CRITICAL-001');
console.log(`\n🔍 Impact Analysis: req:SAFETY-CRITICAL-001`);
console.log(` Total impacted: ${impact.totalImpacted} artifacts`);
impact.impactedArtifacts.forEach(artifact => {
console.log(` - ${artifact.id} (${artifact.kind})`);
console.log(` Path: ${artifact.path.join(' → ')}`);
});
// 4. Find traceability paths
const paths = analyzer.findPaths('req:REQ-001', 'test:HIL-TEST-042');
console.log(`\n🔗 Paths from req:REQ-001 to test:HIL-TEST-042: ${paths.pathCount}`);
paths.paths.forEach((path, idx) => {
console.log(` Path ${idx + 1}: ${path.artifacts.join(' → ')}`);
});
} finally {
// Always close
analyzer.close();
}
}
analyzeCompliance();
Coverage Checking in CI/CD
const { TwpackAnalyzer } = require('@traceweave/trf-analyzer');
async function checkCoverage() {
const analyzer = new TwpackAnalyzer();
try {
await analyzer.loadTwpack('./compliance.twpack');
const reqCoverage = analyzer.coverageAnalysis('requirement', 'verified_by');
const threshold = 95.0; // 95% minimum coverage
if (reqCoverage.coveragePercent < threshold) {
console.error(`❌ Coverage check failed: ${reqCoverage.coveragePercent}% < ${threshold}%`);
console.error('Uncovered requirements:');
reqCoverage.uncoveredArtifacts.forEach(id => console.error(` - ${id}`));
process.exit(1);
}
console.log(`✅ Coverage check passed: ${reqCoverage.coveragePercent}%`);
} finally {
analyzer.close();
}
}
checkCoverage();
Change Impact Assessment
async function assessChange(modifiedArtifactId) {
const analyzer = new TwpackAnalyzer();
try {
await analyzer.loadTwpack('./current.twpack');
const impact = analyzer.impactAnalysis(modifiedArtifactId);
console.log(`\n⚠️ Changing ${modifiedArtifactId} will impact:`);
console.log(` ${impact.totalImpacted} artifacts`);
const impactByKind = {};
impact.impactedArtifacts.forEach(artifact => {
impactByKind[artifact.kind] = (impactByKind[artifact.kind] || 0) + 1;
});
console.log('\n Impact breakdown:');
Object.entries(impactByKind).forEach(([kind, count]) => {
console.log(` ${kind}: ${count}`);
});
// Find all tests that need to be re-run
const testsToRerun = impact.impactedArtifacts
.filter(a => a.kind === 'test')
.map(a => a.id);
console.log(`\n Tests to re-run: ${testsToRerun.length}`);
testsToRerun.forEach(id => console.log(` - ${id}`));
} finally {
analyzer.close();
}
}
assessChange('req:BRAKE-001');
Storage Backend
The analyzer uses SQLite (via better-sqlite3) for efficient graph queries:
- In-memory by default - Fast for packs up to 100K artifacts
- Optimized indexes - Sub-second queries for most operations
- Full SQL access - Available via TwpackQuery package
CLI Usage
All analyzer functionality is available via CLI:
# Statistics
trf analyze stats -f my-pack.twpack
# Impact analysis
trf analyze impact -f my-pack.twpack -a req:REQ-001
# Coverage analysis
trf analyze coverage -f my-pack.twpack -k requirement
# Path finding
trf analyze paths -f my-pack.twpack --from req:REQ-001 --to test:TEST-005
See CLI Reference for details.
Performance
Typical performance on standard hardware:
| Operation | 10K artifacts | 100K artifacts |
|---|---|---|
| Load pack | ~100ms | ~1s |
| Statistics | <10ms | <50ms |
| Impact analysis | <50ms | <200ms |
| Coverage analysis | <50ms | <200ms |
| Path finding | <100ms | <500ms |
See Also
- Query Package - SQL queries on pack data
- Builder Package - Create packs
- CLI Reference - Command-line usage