Skip to main content

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:

Operation10K artifacts100K artifacts
Load pack~100ms~1s
Statistics<10ms<50ms
Impact analysis<50ms<200ms
Coverage analysis<50ms<200ms
Path finding<100ms<500ms

See Also