Risk metrics from your
commit history. Always reproducible.
@nkwib/pr-engine turns a list of git commits into per-file risk metrics. No network. No LLM. No database. Same input always produces the same output, bit-for-bit.
$ npm install @nkwib/pr-engineDeterministic by construction
No Date.now(), no Math.random(), no
unordered iteration in business logic. Same input → same output,
always.
~7.5 ms over 10 k commits
Full pipeline median: analyze() processes 10 000
commits / 500 files in ~7.5 ms. Cochange is the heaviest engine and
still fits in 5 ms.
No fabrication
Every numeric claim points to real commit SHAs in groundedIn — or it's null. The engine never
defaults to 0 when it has no signal.
Inputs in, data out
No fetch, no octokit, no child_process, no DB clients. The package is a pure
function from CommitRecord[] to risk metrics.
Five composable engines
mineCommits · computeChurn · computeCochange · computeHotspots · computeRisk. Use analyze() or wire them up
yourself.
Versioned schema
Output carries an ANALYSIS_SCHEMA_VERSION. Pin to the
major when you integrate; new metrics arrive as new top-level keys
without breaking parsers.
Bring your own git driver
The engine consumes CommitRecord[] — pure data. Two git log passes, parsed by the bundled parseCommitMetadata / parseCommitFiles, and you have a full input. The CLI
package ships a ready-made LocalAdapter if you'd
rather skip the wiring.
import {
parseCommitMetadata, parseCommitFiles, type CommitRecord
} from '@nkwib/pr-engine';
const META = "%x1e%H%x1f%P%x1f%aN%x1f%aI%x1f%B";
const FILES = "\x1eCOMMIT %H";
const meta = parseCommitMetadata(metaStdout);
const files = parseCommitFiles(fileStdout);
const commits: CommitRecord[] = meta.map(
(m) => ({ ...m, filesTouched: files.get(m.sha) ?? [] })
);
Pure data in. Grounded metrics out.
No clock. No PRNG. No network. Run twice, get the same bytes.