@phoenixaihub/behaviorprint
v1.0.1
Published
Behavioral Fingerprinting Engine — detect behavioral regressions in code changes before they reach production
Maintainers
Readme
behaviorprint
Behavioral Fingerprinting Engine for Code Changes
Catch the regressions your tests don't cover — before they hit production 30-90 days later.
The Problem
AI-assisted code changes are fast and pass existing tests. But tests only cover known behaviors. When an AI refactors processPayment(), it might subtly change how null currency codes are handled. Your tests pass. Three months later, 0.3% of payments start failing.
behaviorprint captures the complete behavioral signature of your functions — every edge case, every boundary value, every type coercion quirk — and detects when any of it changes.
How It Works
Before Change After Change
│ │
▼ ▼
┌──────────────┐ ┌──────────────┐
│ Extract AST │ │ Extract AST │
│ functions │ │ functions │
└──────┬───────┘ └──────┬───────┘
▼ ▼
┌──────────────┐ ┌──────────────┐
│ Generate │ │ Generate │
│ input classes│ │ input classes│
│ (boundaries) │ │ (boundaries) │
└──────┬───────┘ └──────┬───────┘
▼ ▼
┌──────────────┐ ┌──────────────┐
│ Probe each │ │ Probe each │
│ function │ │ function │
│ (sandboxed) │ │ (sandboxed) │
└──────┬───────┘ └──────┬───────┘
│ │
└──────────┬──────────────────┘
▼
┌──────────────┐
│ Compare │
│ fingerprints │
└──────┬───────┘
▼
┌──────────────┐
│ Divergence │
│ Report │
└──────────────┘Core Algorithms
- Function Extraction — AST-based (tree-sitter) identification of exported/public functions with arity detection
- Input Class Generation — Automatic boundary values:
0, -1, MAX_SAFE_INTEGER, null, undefined, NaN, Infinity, empty string, empty array, {}, and combinations - Behavioral Probing — Sandboxed execution capturing return values, thrown exceptions, and side effects (console output)
- Fingerprint Comparison — Hash-based comparison of
(input_class → output_signature)maps - Severity Classification —
return→throw= critical,null/undefinedboundary = high, type changes = medium - Coverage Gap Detection — Information-theoretic entropy metric identifying undertested behavioral surfaces
Installation
npm install @phoenixaihub/behaviorprintCLI Usage
Capture fingerprints
# Capture behavioral fingerprints of all exported functions
behaviorprint capture ./src --output before.json
# Make your changes...
# Capture again
behaviorprint capture ./src --output after.jsonCompare fingerprints
behaviorprint compare before.json after.json --output report.jsonExample Output
{
"functions_analyzed": 12,
"identical": 9,
"divergent": 3,
"divergences": [
{
"function": "processPayment",
"file": "src/payments.js",
"input": [0, null],
"before": { "returns": { "success": false, "error": "invalid" } },
"after": { "throws": "TypeError: Cannot read property 'code' of null" },
"severity": "critical",
"production_frequency": "estimated 0.3% of calls"
}
]
}Programmatic API
import { captureFunction, compareFingerprints } from '@phoenixaihub/behaviorprint';
// Capture a single function
const before = captureFunction(oldImplementation, 'processPayment');
const after = captureFunction(newImplementation, 'processPayment');
// Compare
const report = compareFingerprints([before], [after]);
console.log(`${report.divergent} behavioral divergences found`);
for (const d of report.divergences) {
console.log(`${d.severity}: ${d.function} — input: ${JSON.stringify(d.input)}`);
}Full Directory Capture
import { capture, compareFingerprints } from '@phoenixaihub/behaviorprint';
const before = capture('./src-v1');
const after = capture('./src-v2');
const report = compareFingerprints(before.fingerprints, after.fingerprints);Severity Levels
| Severity | Meaning | Example |
|----------|---------|---------|
| critical | Function now throws where it previously returned | null input causes crash |
| high | Null/undefined boundary behavior changed | Silent null → error |
| medium | Return type changed | number → string |
| low | Value changed but type preserved | 42 → 43 |
CI Integration
# .github/workflows/behaviorprint.yml
- name: Capture baseline
run: behaviorprint capture ./src --output baseline.json
- name: Capture current
run: behaviorprint capture ./src --output current.json
- name: Compare
run: |
behaviorprint compare baseline.json current.json --output report.json
cat report.json | jq '.divergent' | grep -q '^0$' || exit 1License
MIT
