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.
skills/hallmark/SKILL.md— Defines the Hallmark skill and registers verbs likeauditviaskill.registerVerb('audit', async (args) => { ... }).skills/hallmark/references/anti-patterns.md— Stores the human-maintained catalogue of anti-patterns and their severity weights.README.md— Documents CLI usage for the audit command.package.json— Lists runtime dependencies such as@babel/parserand 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:
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
auditverb is registered as a skill inskills/hallmark/SKILL.mdand triggered viahallmark audit <path>. - It loads a weighted anti-pattern catalogue from
skills/hallmark/references/anti-patterns.mdusingloadAntiPatternCatalogue(). - Source files are parsed into ASTs through
parseToAST()—JavaScript and TypeScript files use@babel/parser—then traversed to match structural signatures viamatchesPattern(). - 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →