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

> Learn how the hallmark audit verb scores your code against anti-patterns by parsing ASTs, matching signatures, and normalizing severity to a 0-100 score.

- Repository: [Hassan El Mghari/hallmark](https://github.com/Nutlope/hallmark)
- Tags: how-to-guide
- Published: 2026-07-21

---

**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`](https://github.com/Nutlope/hallmark/blob/main/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](https://github.com/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`](https://github.com/Nutlope/hallmark/blob/main/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:

```javascript
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.

- **[`skills/hallmark/SKILL.md`](https://github.com/Nutlope/hallmark/blob/main/skills/hallmark/SKILL.md)** — Defines the Hallmark skill and registers verbs like `audit` via `skill.registerVerb('audit', async (args) => { ... })`.
- **[`skills/hallmark/references/anti-patterns.md`](https://github.com/Nutlope/hallmark/blob/main/skills/hallmark/references/anti-patterns.md)** — Stores the human-maintained catalogue of anti-patterns and their severity weights.
- **[`README.md`](https://github.com/Nutlope/hallmark/blob/main/README.md)** — Documents CLI usage for the audit command.
- **[`package.json`](https://github.com/Nutlope/hallmark/blob/main/package.json)** — Lists runtime dependencies such as `@babel/parser` and other language parsers.

## 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:

```bash
hallmark audit ./src

```

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

```text
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:

```javascript
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`](https://github.com/Nutlope/hallmark/blob/main/skills/hallmark/references/anti-patterns.md):

```markdown

### 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`](https://github.com/Nutlope/hallmark/blob/main/skills/hallmark/SKILL.md) and triggered via `hallmark audit <path>`.
- It loads a weighted anti-pattern catalogue from [`skills/hallmark/references/anti-patterns.md`](https://github.com/Nutlope/hallmark/blob/main/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`](https://github.com/Nutlope/hallmark/blob/main/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`](https://github.com/Nutlope/hallmark/blob/main/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`](https://github.com/Nutlope/hallmark/blob/main/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.