AI Coding Tip 027 - Force Code Standards

Wait 5 sec.

Style errors double when nobody enforces them.TL;DR: Wire your standards into hooks, skills, and a judge, so the harness blocks violations before a human opens the diff.Common Mistake ❌You paste your coding standards into AGENTS.md and trust the AI to remember them.Then a human reviewer manually checks naming, indentation, and spacing on every pull request.Nobody wires a hook, a skill, or a judge that blocks the diff before a human ever opens it.The standards live in prose, and prose is optional.Problems Addressed 😔A CodeRabbit analysis of 470 pull requests found AI-generated code carries roughly 1.7x more defects than human-only code, and nearly 2x more naming and style consistency errorsHuman reviewers burn attention on indentation and casing instead of design, feeding the same broken windows that erode a codebase over timeEnforcement depends on someone remembering to check, so it drifts the moment nobody's watchingThe AI violates a rule it read in prose, because prose isn't a gate, only a suggestionTwo human reviewers catch two different subsets of the same code without standardsHow to Do It 🛠️Turn each standard into a machine-checkable rule instead of a paragraph of prose.Wire a pre-commit or pre-merge hook that runs the linter automatically on every change.Add a validator skill that reads the rule set fresh and re-checks the whole diff, not just what the AI remembers.Route ambiguous rules, like naming intent, to a large language model (LLM) judge instead of a human reviewer.Block the commit, the merge, or the session end until every gate reports zero violations.Log every violation the judge catches as a new rule, so the harness never misses it again.Benefits 🎯Consistent gate: Every diff hits the same rule set, so two reviewers never catch two different subsets of the same violation.Faster reviews: Humans spend their attention on design and correctness, not indentation or casing.No memory decay: A skill reads the standards file fresh every session instead of trusting what the AI claims to remember.Judge for nuance: An LLM judge catches the semantic violations a regular expression can't parse, like a misleading name.Compounding rules: Every violation the judge finds becomes a new check, so the harness gets stricter over time.Measurable drop: You can track the naming and style defect rate over time and watch it fall toward zero.Context 🧠Standards enforcement isn't new.Stephen C. Johnson wrote the first lint in 1978 to catch mistakes in C code that nobody wanted to check by eye.Checkstyle, PMD, and ESLint followed, each one refusing to trust a human to notice a mixed indentation.SonarQube added a server that gates a whole pipeline, not just a single file.Mago does the same for PHP now, running a linter, a formatter, and a static analyzer in one Rust binary fast enough to run on every keystroke.None of these tools ever asked a human to vote on a tab versus a space or a mixedCase versus snake_case name.AI coding didn't remove that need.It multiplied it.A CodeRabbit analysis of 470 pull requests found AI-generated code carries about 1.7x more defects overall than human-only code.Naming and style consistency errors came in at nearly 2x, the exact class of mistake a linter was built to catch decades ago.A model can now write in any human language, misspell an identifier, or reorder parameters inconsistently across two files that it never compared side by side.A linter still catches the syntactic version of these mistakes.The semantic version, like a name that lies about its role, needs a judge who reads intent, not just tokens.That's where an LLM-as-judge step fits: a second AI pass, wired into the same harness that runs the linter, checking the rules no regular expression can express.Skills are the natural home for that judge.A skill reads the standards file fresh every time, instead of trusting a memory that decays across sessions.Pair the judge with a criteria check before the task ends, so the AI can't say a task is done until the standards gate reports zero violations.A gate that blocks the diff is just another way to force the AI to obey you, not by asking nicely, but by refusing to let a violation through.This doesn't replace reviewing every line before commit.It removes the mechanical part of that review, so a human is free to judge design instead of counting spaces.When the judge catches a new violation, log it the same way you'd log a pitfall, so the harness never makes that mistake twice.Prompt Reference 📝Bad Prompt 🚫Please follow our coding standards for this feature.Use consistent naming and formatting like the rest of the codebase.I'll check it during code review before we merge.Good prompt 👉Before you say this task is done, run this standards checklist:- [ ] Run the linter on every changed file, fix every violation.- [ ] Run the formatter, don't hand-format a single line.- [ ] Invoke the code-standards-validator skill on the full diff.- [ ] Check every identifier: no abbreviations, no misleading names.- [ ] Check indentation matches the project config, no mixed tabs.- [ ] Check casing: one convention, no mixedCase next to snake_case.- [ ] Check parameter order against other functions in the file.- [ ] Check spelling in every identifier, comment, and string.- [ ] Judge comment quality: flag dead comments and restated code.- [ ] Judge naming intent: does each name say what it does?- [ ] Confirm no file mixes languages in identifiers or comments.- [ ] Log any new violation type as a rule for the next run.- [ ] Don't report the task done until every box above is checked.Show me the completed checklist, not just the final code.Considerations ⚠️A linter still beats an LLM judge on speed and cost for anything syntactic.Reserve the judge for rules that need intent, not tokens.A gate that blocks too aggressively gets bypassed with --no-verify, which defeats the whole point.Review the judge's false positives the same way you'd review a flaky linter rule.Type 📝[X] Semi-AutomaticLimitations ⚠️An LLM judge costs tokens and time on every gate, so it doesn't replace a linter.It complements one.A judge can disagree with itself across two runs on borderline style calls, so keep the deterministic rules in the linter and reserve the judge for what's genuinely ambiguous.Tags 🏷️Knowledge ManagementLevel 🔋[X] IntermediateRelated Tips 🔗https://hackernoon.com/ai-coding-tip-004-why-you-should-use-modular-skills?embedable=truehttps://hackernoon.com/ai-coding-tip-006-review-every-line-before-commit?embedable=truehttps://hackernoon.com/ai-coding-tip-011-how-to-initialize-agentsmd?embedable=truehttps://hackernoon.com/ai-coding-tip-015-force-the-ai-to-obey-you?embedable=truehttps://hackernoon.com/ai-coding-tip-016-your-pull-requests-should-teach-your-next-ai-agent?embedable=truehttps://hackernoon.com/ai-coding-tip-019-tell-the-ai-why-not-just-what?embedable=truehttps://hackernoon.com/ai-coding-tip-022-give-ai-a-harness-to-work-with?embedable=truehttps://hackernoon.com/ai-coding-tip-024-force-a-criteria-check-before-the-task-ends?embedable=truehttps://hackernoon.com/ai-coding-tip-025-add-a-pitfallsmd-next-to-every-skillmd?embedable=trueConclusion 🏁A linter never asks permission to reject bad code.Neither should your harness.Wire the standards into hooks, skills, and a judge, so the diff gets rejected before a human ever has to say so.More Information ℹ️Lint (software) - Wikipediahttps://www.coderabbit.ai/blog/state-of-ai-vs-human-code-generation-report?embedable=truehttps://arxiv.org/pdf/2508.02994?embedable=truehttps://github.com/lukehutch/awesome-static-analysis?embedable=trueAlso Known As 🎭Harness-Enforced-StandardsMachine-Judged-StyleStandards-as-CodeLinter-Native-ReviewTools 🧰https://mago.carthage.software/?embedable=truehttps://eslint.org/?embedable=truehttps://www.sonarsource.com/products/sonarqube/?embedable=truehttps://github.com/PHPCSStandards/PHP_CodeSniffer?embedable=truehttps://docs.astral.sh/ruff/?embedable=truehttps://rubocop.org/?embedable=truehttps://checkstyle.sourceforge.io/?embedable=truehttps://golangci-lint.run/?embedable=truehttps://doc.rust-lang.org/clippy/?embedable=trueDisclaimer 📢The views expressed here are my own.I am a human who writes as best as possible for other humans.I use AI proofreading tools to improve some texts.I welcome constructive criticism and dialogue.I shape these insights through 30 years in the software industry, 25 years of teaching, and writing over 500 articles and a book.This article is part of the AI Coding Tip series.https://maximilianocontieri.com/ai-coding-tips?embedable=true