A coding standard sets out the rules a team agrees its code will meet. Some rules cover how the code looks, such as indentation, line length and naming. Others set limits a tool can count, such as how long a function may be or how many paths run through it.

A standard only sticks where something checks it. Put each rule a tool can check into your linter’s config as an error. A linter reads code without running it and reports every rule the code breaks. Then run every check in CI, short for continuous integration, on every pull request. A change that breaks a rule can’t merge, whether a person or a coding agent wrote it. The rules no tool can check go on a short list for review.

Developer Coding agent Lint and formatting Type check Duplication Unit tests and coverage End-to-end tests Security audit Any error goes back for a fix Ready to merge
Every change meets the same checks, whoever wrote it. A check that fails sends the change back to its author.

What coding standards cover

Coding style usually means layout: indentation, spacing, line length and where the braces go. Code guidelines, or conventions, add naming, file layout, imports and error handling. A full coding standard adds limits that a tool can measure on every change.

Google’s style guide index (2026) calls a style guide a set of conventions, some of them arbitrary. It adds that a large codebase is much easier to understand when all of it is in one style. PEP 8, by Guido van Rossum, Barry Warsaw and Alyssa Coghlan (2001), starts from the same place. It notes that code is read much more often than it’s written.

Which arbitrary choice a guide makes hardly matters, because the value comes from everyone following the same rules. PSR-12 (2019), PHP-FIG’s coding style for PHP, puts the guide’s benefit in the sharing of its rules.

Coding standards examples

Here are four standards and the tools that check them:

Standard Language What it covers What checks it
PEP 8 Python Layout, whitespace, comments and naming Ruff, whose E, W and N rules come from pycodestyle and pep8-naming
PSR-12 PHP Files, lines, indenting, declarations and control structures PHP_CodeSniffer, which checks against PSR-12 unless told not to
Prettier’s output JavaScript, TypeScript, CSS and more Formatting only Prettier rewrites each file in its own style
The Prickles canon TypeScript, JavaScript, Python, Java and PHP Size, complexity, duplication and naming, among 51 tenets A lint config for each language, plus rule files for coding agents

Prettier’s Why Prettier? (2026) gives an end to arguments over style as the main reason to adopt it. Google’s The Standard of Code Review (2026) treats the style guide as the final word on style, and any style point it doesn’t cover as personal preference. Pick a guide and let a formatter apply as much of it as it can. A review then no longer has to settle layout.

A written rule is a request

A rule in a wiki is followed while people remember it and a reviewer spots the miss. A coding agent is in the same position with its instruction file. Anthropic’s How Claude remembers your project (2026) says Claude reads CLAUDE.md as context rather than as configuration it must obey. It adds that strict compliance isn’t guaranteed.

Anthropic’s Best practices for Claude Code (2026) contrasts an instruction with a hook. A hook is a script that Claude Code runs automatically at a set point, such as after each edit. In the page’s words, “Unlike CLAUDE.md instructions which are advisory, hooks are deterministic and guarantee the action happens.”

Yujun Zhou and colleagues measured the gap in Getting Better at Working With You (2026). They ran six models on 19 coding-agent tasks with 29 checks, built from corrections one researcher made to coding agents over about two months. With every rule placed in the agent’s context as text, the agents passed 55.0% of the checks. With the same rules compiled into checks the run had to pass before it could finish, they passed 70.1%. With no rules at all, they passed 31.6%.

So put every rule a tool can check where the tool checks it, and make the check fail. TA1 Linter as Law makes every gate an error, never a warning. ESLint’s Configure Rules page (2026) shows why the severity matters. A rule set to "warn" leaves the exit code alone. A rule set to "error" makes ESLint exit with 1. CI fails a step that exits with anything but 0, so only an error stops the build.

These core ESLint rules set five of the canon’s limits, and its magic-number rule, as errors in eslint.config.mjs:

const LIMITS = {
  complexity: 3,
  depth: 3,
  params: 3,
  functionLines: 15,
  fileLines: 150,
};

export default [
  {
    files: ["**/*.js", "**/*.mjs"],
    rules: {
      complexity: ["error", LIMITS.complexity],
      "max-depth": ["error", LIMITS.depth],
      "max-params": ["error", LIMITS.params],
      "max-lines-per-function": ["error", { max: LIMITS.functionLines, skipBlankLines: true }],
      "max-lines": ["error", { max: LIMITS.fileLines, skipBlankLines: true }],
      "no-magic-numbers": ["error", { ignore: [-1, 0, 1] }],
    },
  },
];

On 12 October 2026, with ESLint 9.39.5, this config passed its own rules. A function with four paths and two bare numbers failed it with three errors. With each "error" changed to "warn", the same three problems came back as warnings and the run passed.

Code quality metrics you can gate on

A metric is worth a gate when a tool can count it on every change. The count should also say something about how hard the code is to read or change. These are the limits the Prickles canon sets. Each pack’s lint config enforces the ones its language’s tools can measure.

Metric Canon limit What it counts
Cyclomatic complexity 3 Independent paths through one function
Nesting depth 3 Blocks inside blocks
Function length 15 lines Lines in one function, leaving out blank lines
File length 150 lines Lines in one file, leaving out blank lines
Statements 10 Statements in one function
Parameters 3 Arguments one function takes
Cognitive complexity 15 How hard a function is to follow, weighted for depth
Duplication 50 tokens Smallest copied block counted as a clone
Magic numbers None beyond -1, 0 or 1 Bare numbers in the code

Cyclomatic complexity starts at one and adds one for each branch in the function. A magic number is a number whose meaning isn’t named, such as 18 where ADULT_AGE would say what it is. For duplication, jscpd counts tokens, the words and symbols a parser splits code into.

These limits are strict on purpose. S2 Cyclomatic Caps explains why the complexity cap is 3, and Code complexity covers the metric in depth. The same cap is set differently in each pack’s tools:

  • TypeScript and JavaScript use ESLint’s complexity rule, set to 3.
  • Python uses Ruff’s max-complexity, set to 3.
  • Java uses PMD’s CyclomaticComplexity, with methodReportLevel set to 4, because PMD reports a method that reaches the level it’s given.
  • PHP uses PHP_CodeSniffer’s Generic.Metrics.CyclomaticComplexity, set to 3.

How to measure code quality

Count what a tool can count, give each count a limit and fail any change that crosses one. Measured that way, each change passes or fails whoever reviews it.

This site’s own repository works this way. Its CI runs these checks on every pull request and every push to main, and any failure fails the run. All of them passed on main on 12 October 2026.

Check Tool Fails the run when
Lint ESLint with its sonarjs and unicorn plugins Any rule reports an error, including 15 lines a function, 150 a file and complexity 3
Formatting Prettier A file differs from Prettier’s output
Types tsc and astro check There’s a type error anywhere
Duplication jscpd A copied block of 50 tokens or more appears anywhere in the source
Unit tests Vitest A test fails, or coverage of lines, functions, branches or statements falls below 100%
Build astro build Astro can’t build the site
End-to-end tests Playwright, running scenarios written in Gherkin A scenario fails in the browser
Security audit npm audit A dependency has a known vulnerability rated high or above

Most of the same checks run on a developer’s machine with one command, npm run quality. It also runs a Sonar analysis locally. P4 Continuous Quality Feedback asks for this, so the check runs while the change is fresh, before CI sees it.

Over time, count the exceptions. Every comment that disables a rule on a line, and every folder a rule is switched off for, is a place where the standard doesn’t apply. On 12 October 2026, the source of the repository behind this site held no inline disable comments.

How to set up coding standards for a team

  1. Pick a published style guide for each language, and let a formatter apply as much of it as it can.
  2. Write each limit into the lint config as an error before the first violation is merged, as TA1 Linter as Law asks.
  3. Give the team one command that runs every check, and run it while you work, before CI sees the change, as P5 Shift-Left Quality describes. A pre-commit hook can run the fast checks before each commit.
  4. Run the same checks in CI on every pull request, and make the CI job a required status check. GitHub’s About protected branches (2026) says every required check must pass before anyone can merge into a protected branch.
  5. Put the rules in your coding agent’s instruction file too, so it writes to the standard the first time. CLAUDE.md vs AGENTS.md covers which file each agent reads.
  6. When a rule trips, fix the code. For older code that can’t meet a limit yet, switch the rule off for that folder alone. Keep a plan to remove the exception, as TA2 Duplication Detection does for duplicates.
  7. Write the checks no tool can make as a short definition-of-done checklist, and review each change against it, as P3 Definition of Done sets out.

A lint error gives a coding agent its feedback. Anthropic’s best practices tell you to give Claude a check it can run, such as tests, a build or a linter. Without one, Claude stops when the work looks done.

John Yang and colleagues measured what a lint check does for an agent in SWE-agent (2024). With GPT-4 Turbo on the 300 tasks of SWE-bench Lite, SWE-agent resolved 18.0% when its edit command refused edits that failed a lint check for syntax errors. Without the check, it resolved 15.0%.

What a linter can’t check

Each Prickles pack’s lint config lists, in its header, the tenets it enforces out of the canon’s 51:

Language Lint tools in the pack Tenets the config enforces
TypeScript ESLint and its plugins 19
JavaScript ESLint and its plugins 16
Python Ruff and Pylint 16
Java PMD 13
PHP PHP_CodeSniffer with PHPMD and phpmnd 12

Other tenets take judgement, such as whether a name says what the code does or whether a function has one reason to change. TA1 asks you to name the line between what the linter checks and what it can’t, so nobody mistakes the lint gate for the whole standard. A short checklist and a reviewer cover what lies beyond it, and AI code review has a checklist for that review.

Each Prickles pack carries both halves. The lint config fails the build on what a tool can count. The agent’s rule files carry every tenet. A short entry that the agent always loads holds each tenet’s rule. The rest of the canon loads when the work needs it. The implementation page shows what each agent and language gets.