Files
Paul HittandClaude Opus 5.5 23d09feedd Publish to the GitLab package registry on version tags
The README's install line failed: the package was never published, and
nothing told npm where the @extant2000 scope lives. A tag like v1.2.3 now
publishes to this project's registry with CI_JOB_TOKEN, and the README
sets the scope's registry before installing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 16:41:34 -04:00

3.2 KiB

BlastRadius

Detects when copies of the same function in different codebases drift apart, and names which copies disagree. It is used in Hitt Hosting products.

What it does and why

When the same logic lives in more than one place (two services, a vendored copy, a CommonJS and a TypeScript version), a fix tends to land in only one of them. Each copy looks fine on its own. Only a comparison shows that they no longer agree, and by then the unfixed copy has been running for a while.

BlastRadius takes the source text of each copy and the name of the function to compare. It extracts the function by brace matching, strips comments and normalises whitespace, fingerprints the result, and groups the copies by fingerprint. More than one group means drift. The largest group comes first, which usually tells you which side has the fix and which side missed it.

Comments and formatting are ignored because copies may be documented differently but must behave the same. Comparing raw text would fire on a typo fix and train people to update the pinned value without reading, which brings back the drift the check exists to catch. The extraction is not a parser, so it works across CommonJS, ESM and TypeScript without a toolchain per dialect.

A copy where the function cannot be found is a failure, not a pass. It may have been renamed, split or deleted, and a guard that cannot find its subject is not passing. This holds even when only one copy was located.

Fewer than two located copies, with none missing, is reported as not assessed: one copy cannot disagree with itself, and calling that "in sync" would let a deleted sibling read as a clean result. An in-sync pass cites the copies it compared, because a pass that cannot name what it compared is only asserted.

The library is pure and has no filesystem access; you read the files. Reports use the @extant2000/evidence-record format, and every copy is cited by its path when you give one, or by its label.

Usage

import { compareImplementations, toReport, formatDrift } from '@extant2000/blast-radius'

const withCheck = 'function canSend(c) {\n  if (!c.postalAddress) return false\n  return true\n}'
const withoutCheck = 'function canSend(c) {\n  return true\n}'

const result = compareImplementations([
  { label: 'web', path: 'web/lib/send.ts', source: withCheck },
  { label: 'worker', path: 'worker/lib/send.ts', source: withCheck },
  { label: 'cli', path: 'cli/lib/send.ts', source: withoutCheck },
], 'canSend')

result.inSync                        // false
result.groups.map(g => g.labels)     // [['web', 'worker'], ['cli']]
result.missing                       // []

const report = toReport(result)      // evidence-record report
console.log(formatDrift(result, { evidence: 'full' }))

The report has one critical finding, "canSend has drifted across 2 variants", citing all three files with the variant each belongs to (2 of 3 and 1 of 3).

extractFunction(), codeOnly() and fingerprint() (FNV-1a) are exported for use on their own.

Install

The package is published to the GitLab package registry, so point the @extant2000 scope there first:

npm config set @extant2000:registry https://gitlab.com/api/v4/packages/npm/
npm install @extant2000/blast-radius

License

MIT. See LICENSE.