How the Hallmark Audit Verb Scores Existing Code Against Anti-Patterns

The hallmark audit verb evaluates your codebase by parsing source files into ASTs, matching structural signatures against a weighted anti-pattern catalogue stored in skills/hallmark/references/anti-patterns.md, and normalizing the total severity weight to a 0–100 score.

The Hallmark audit verb is a core feature of the Nutlope/hallmark CLI tool. It provides a systematic way to measure code quality by scoring existing code against a curated Markdown catalogue of anti-patterns. The entire flow is implemented as a registered skill inside the repository, making the audit both configurable and extensible.

How the Hallmark Audit Verb Analyzes Code

The audit process defined in the repository follows three distinct stages: catalogue loading, AST-based scanning, and weighted scoring.

Loading the Anti-Pattern Catalogue

Hallmark begins every audit by reading the anti-pattern catalogue from skills/hallmark/references/anti-patterns.md. This Markdown file lists every known anti-pattern alongside its description and a numeric severity weight. The audit verb parses this file at runtime through an internal loadAntiPatternCatalogue() helper and builds an in-memory map that links each pattern signature to its weight.

Because the catalogue is plain Markdown, contributors can adjust severity or add new patterns without modifying source code.

Scanning Source Files with AST Parsing

When you run hallmark audit <path>, the verb invokes collectSourceFiles(args.path) to walk the supplied directory tree and gather every source file. It then parses each file into an Abstract Syntax Tree (AST) via parseToAST(file.content) using the language-specific parsers bundled with Hallmark, such as @babel/parser for JavaScript and TypeScript.

During traversal, the audit engine checks AST nodes against the structural signatures from the catalogue. When matchesPattern(ast, pattern.signature) returns true, the engine records the finding, the file path, and the line number via locateLine(ast, pattern.signature). Each match is stored with the anti-pattern’s weight for later aggregation.

Calculating the Normalized Audit Score

After the scan completes, Hallmark aggregates the collected weights. It sums the severity of all detected anti-patterns, then normalizes that total against the maximum possible score derived from the full catalogue. The final result is a 0–100 integer, where 0 means no anti-patterns were found and 100 indicates the codebase is saturated with high-severity patterns. The internal logic implemented in the skill definition resembles:

const totalWeight = findings.reduce((s, f) => s + f.weight, 0);
const maxPossible = catalogue.reduce((s, p) => s + p.weight, 0);
const score = Math.round((totalWeight / maxPossible) * 100);

reportAuditResult(score, findings);

The reportAuditResult() function then prints the score and a detailed breakdown of every violation.

Key Source Files and Skill Registration

The audit verb is implemented as a registered skill in the Hallmark codebase. According to the source analysis, the wiring lives in the skill definition file and relies on a small set of critical paths.

Practical Examples for Running and Extending Hallmark Audits

Running a Full Audit from the CLI

To score an existing project, pass the target directory to the audit verb:

hallmark audit ./src

Typical output lists each anti-pattern, its location, and its contribution to the total score:

Audit Score: 27 / 100

Detected anti-patterns:
  • src/utils/helpers.js:12 – "Deeply nested callbacks" (weight 5)
  • src/components/Widget.tsx:45 – "Excessive prop drilling" (weight 8)
  • src/api/client.ts:78 – "Hard-coded URLs" (weight 4)

Programmatic Use in Node.js

You can invoke the audit verb from another script by spawning the Hallmark CLI:

const { exec } = require('child_process');

exec('hallmark audit ./my-lib', (err, stdout) => {
  if (err) throw err;
  console.log('Audit result:', stdout);
});

Adding a Custom Anti-Pattern

Because the catalogue is Markdown-based, extending it requires only a new entry in skills/hallmark/references/anti-patterns.md:


### Unused imports

- **Description:** Files contain imports that are never referenced.
- **Signature:** `ImportDeclaration` nodes with no Identifier usages.
- **Weight:** 3

The next hallmark audit run will automatically detect and score occurrences of this pattern.

Summary

  • Hallmark’s audit verb is registered as a skill in skills/hallmark/SKILL.md and triggered via hallmark audit <path>.
  • It loads a weighted anti-pattern catalogue from skills/hallmark/references/anti-patterns.md using loadAntiPatternCatalogue().
  • Source files are parsed into ASTs through parseToAST()—JavaScript and TypeScript files use @babel/parser—then traversed to match structural signatures via matchesPattern().
  • Matches are aggregated by weight and normalized to a 0–100 score, where lower scores indicate cleaner code.
  • The catalogue is plain Markdown, so teams can add or adjust anti-patterns without redeploying the tool.

Frequently Asked Questions

What does a Hallmark audit score of 0 mean?

A score of 0 means the audit found no matching anti-patterns in the scanned codebase. Because Hallmark normalizes findings against the maximum possible severity, a zero score indicates the project triggered none of the weighted structural signatures defined in the catalogue.

Where does Hallmark store its anti-pattern definitions?

Definitions live in skills/hallmark/references/anti-patterns.md inside the repository. This Markdown file is read at runtime by the loadAntiPatternCatalogue() function and mapped into memory before the AST scanning phase begins.

Can I add custom anti-patterns to the Hallmark audit?

Yes. Adding a custom anti-pattern is a matter of appending a new Markdown entry to skills/hallmark/references/anti-patterns.md with a Signature, Description, and Weight. The next time you run hallmark audit, the registered skill automatically picks up the new pattern and includes it in the scoring calculation.

Which parsers does Hallmark use to analyze code?

According to the repository’s package.json and skill implementation, Hallmark bundles language-specific parsers such as @babel/parser for JavaScript and TypeScript. These parsers generate the ASTs that the audit verb traverses when matching code against anti-pattern signatures.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →