Implementation

Make the canon enforce itself.

Download the canon as a lint config in your project's language plus a set of rule files for your AI coding agent. Pick both below.

§1

Pick your language

Pick the language of your project. The choice also sets the language used in every code sample and enforcement table on the rest of the site.

§2

Enforcement

One config file per language, and two for PHP. Every rule has an inline comment naming the tenet it enforces and a link to the canon entry. Drop the files in your repo, install the dependencies and the rules run.

TypeScript · primary toolchain: ESLint (flat config)

Config file: eslint.config.mjs

eslint.config.mjs375 lines
// =============================================================================
// Prickles canon — TypeScript flat config (eslint.config.mjs) · v4.0.0
// Source of truth: https://prickles.org/implementation
//
// What this file enforces (19 of 51 tenets):
//   F1 F2 F3 F4 F5 F6      ·  Foundations
//   A1 A2 A3 A11           ·  Architecture (folder + import discipline)
//   S2 S3 S4 S5            ·  Style (caps, params, guards, inline-first)
//   T2                     ·  Types (no escape hatches)
//   P5                     ·  Shift-Left Quality (a11y safety in JSX)
//   TA1 TA2                ·  Tooling (linter as law, detect duplication)
//   TS5                    ·  Testing (locate by structure — a11y roles)
//
// What this file CANNOT enforce — the canon carries these on other surfaces:
…

Install steps

  1. Install the dependencies:
    npm i -D "eslint@^9.38 || ^10" @eslint/compat@2 typescript-eslint@8 eslint-config-prettier@10 eslint-plugin-prettier@5 eslint-plugin-import-x@4 eslint-plugin-jsx-a11y-x@0.2 eslint-plugin-sonarjs@4 eslint-plugin-unicorn@65 jscpd@5 prettier@3
  2. Drop the config above into eslint.config.mjs at your repo root. If the repo already has its own ESLint config, merge the two into one file: ESLint reads only one. If your framework has an ESLint plugin, keep it in that file or add it: the canon checks .vue, .svelte and .astro files through the plugin's parser. typescript-eslint 8 works with TypeScript up to 6.0, not 7. If your project has no TypeScript yet, or has TypeScript 7, install 6.0 before the lint tools: npm i -D typescript@~6.0 In an Angular workspace with no ESLint yet, add angular-eslint at your Angular major version before you merge, such as ng add angular-eslint@21 for Angular 21. Without the version, ng add installs the newest angular-eslint, which refuses an older workspace. In a Nuxt project, the eslint.config.mjs Nuxt sets up exports withNuxt(), which returns a promise of Nuxt's config rather than an array. Keep its import of withNuxt and add ...(await withNuxt()) to this pack's defineConfig array. When you merge, import each name once. SvelteKit's config, for one, imports defineConfig and includeIgnoreFile from eslint/config and prettier from eslint-config-prettier, as this pack's does: delete its copies of those imports and its own includeIgnoreFile(...) entry, since this pack's config already ignores what .gitignore ignores. If a subfolder has its own ESLint config, as monorepo packages often do, ESLint 10 checks that folder's files against that config alone, and so does ESLint 9 when you run it from the folder. Import this pack's eslint.config.mjs into that config and spread it into the array it exports. Then format it with your project's own Prettier settings: npx prettier --write "eslint.config.*"
  3. Run the gate:
    npx eslint . && npx jscpd . --ignore "**/node_modules/**,**/dist/**,**/build/**,**/coverage/**,**/.nuxt/**,**/.output/**" --format "typescript,tsx,javascript,jsx,vue,svelte,astro" --threshold 0 && npx prettier --check .
  4. Wire the gate into CI: a quality script (or its build-tool equivalent) that fails the build on any rule violation.
§3

AI rules

The rule files each agent reads, in the form that agent loads them. In the Recommended layout a short entry holds every tenet's rule and is always loaded, and the rest of each pillar loads when the work needs it. In the Strict layout the whole canon is always loaded. Together, the files hold every word of each tenet's entry on the canon.

Claude Code · 10 files: the entry and 9 pillar files, plus a review file

Claude Code loads .claude/rules/prickles-canon.md, which has no paths frontmatter, when a session starts and again after compaction. The six code pillars' rules carry paths: and load when Claude Code reads or edits a matching file. Process, AI Collaboration and Tooling are skills in .claude/skills. An optional REVIEW.md gives Claude Code Review every tenet's rule.

Showing the Recommended layout for TypeScript. Change the language in §1 and the layout in §4.

The entry: every tenet's rule

Always loaded. Each tenet's ID, name and rule under its pillar's heading, which names the file that holds the rest of the pillar and says when to read it.

.claude/rules/prickles-canon.md84 lines
# Prickles canon v4.0.0: the 51 tenets

Every tenet below binds any code you write, change, test or review in this repository. Each line is the tenet's rule. The file named in each heading holds the rest of that pillar's tenets and binds you exactly as this file does. Claude Code also loads the Foundations, Architecture, Style, Types & Schema, Testing and Patterns files by itself when you read or edit a file they match.

IMPORTANT: reading a pillar's file is a precondition. Read it with your file-read tool before your first edit of the kind its heading names, and again after your context is compacted.

## Foundations (F1–F6). Before you write or change source code, read `.claude/rules/prickles-foundations.md`.

- **F1 Single Responsibility Principle.** One obvious job per function, class, or module. When a second concern shows up in the same unit, peel it out so each piece has its own reason to change.
- **F2 Intention-Revealing Names.** Use names that answer why this exists and what it does in the domain vocabulary. If the signature does not hold the meaning, rename.
- **F3 Don't Repeat Yourself.** Give every fact, rule and decision in the system one home. If you find yourself typing the same logic, the same literal or the same shape twice, the second copy is a bug looking for a deadline.
- **F4 Simplicity.** Build for the requirement at hand, not the speculative future. No line of code is cheaper than the one you didn't write, and speculative generality is debt with no creditor.
- **F5 Self-Documenting Code.** Do not add comments that explain what the code does. If a reader needs help, improve names, extract functions, add types, or add tests until the code tells the story.
- **F6 Encapsulation.** Hide the inside of your code. Callers should only call methods: never read or change fields directly. The method names are the contract. The body of the code is private and free to change.
…

Foundations pillar

Loads by itself when Claude Code reads or edits a file that matches its paths.

.claude/rules/prickles-foundations.md73 lines
---
paths:
  - "**/*.ts"
  - "**/*.tsx"
  - "**/*.mts"
  - "**/*.cts"
  - "**/*.vue"
  - "**/*.svelte"
  - "**/*.astro"
---

Contents: F1 Single Responsibility Principle, F2 Intention-Revealing Names, F3 Don't Repeat Yourself, F4 Simplicity, F5 Self-Documenting Code, F6 Encapsulation.

The rest of the Foundations tenets of the Prickles canon, v4.0.0. Each tenet's first paragraph is its rule, in the always-loaded Prickles entry. What follows binds you exactly as that rule does.
…

Architecture pillar

Loads by itself when Claude Code reads or edits a file that matches its paths.

.claude/rules/prickles-architecture.md103 lines
---
paths:
  - "**/*.ts"
  - "**/*.tsx"
  - "**/*.mts"
  - "**/*.cts"
  - "**/*.vue"
  - "**/*.svelte"
  - "**/*.astro"
---

Contents: A1 Screaming Architecture, A2 Three-Tier Hoisting, A3 Stable Dependencies Principle, A4 Common Closure Principle, A5 Thin Handlers, A6 Bounded Contexts, A7 Coupling First, A8 Push to the Source of Truth, A9 Liskov Substitution Principle, A10 Interface Segregation Principle, A11 Dependency Inversion Principle.

The rest of the Architecture tenets of the Prickles canon, v4.0.0. Each tenet's first paragraph is its rule, in the always-loaded Prickles entry. What follows binds you exactly as that rule does.
…

Style pillar

Loads by itself when Claude Code reads or edits a file that matches its paths.

.claude/rules/prickles-style.md47 lines
---
paths:
  - "**/*.ts"
  - "**/*.tsx"
  - "**/*.mts"
  - "**/*.cts"
  - "**/*.vue"
  - "**/*.svelte"
  - "**/*.astro"
---

Contents: S2 Cyclomatic Caps, S3 Parameter Object, S4 Guard Clauses, S5 Inline-First.

The rest of the Style tenets of the Prickles canon, v4.0.0. Each tenet's first paragraph is its rule, in the always-loaded Prickles entry. What follows binds you exactly as that rule does.
…

Types & Schema pillar

Loads by itself when Claude Code reads or edits a file that matches its paths.

.claude/rules/prickles-types.md60 lines
---
paths:
  - "**/*.ts"
  - "**/*.tsx"
  - "**/*.mts"
  - "**/*.cts"
  - "**/*.vue"
  - "**/*.svelte"
  - "**/*.astro"
  - "**/*.schema.json"
  - "**/*.sql"
  - "**/*.prisma"
  - "**/*.graphql"
  - "**/*.proto"
…

Process pillar

A skill: the agent sees its description and reads the rest when the task needs it.

.claude/skills/prickles-process/SKILL.md73 lines
---
name: prickles-process
description: "Use at the start of every task in this repository, and before declaring it done, committing or opening a pull request. Holds the rest of the Prickles Process tenets, P1 Test-First Development, P2 Spec-First Execution, P3 Definition of Done, P4 Continuous Quality Feedback, P5 Shift-Left Quality, P6 Leave it Better Than You Found it, P7 Short-Lived Branches with AI+Human Review, P8 Architecture Decision Records, which bind you exactly as the always-loaded Prickles entry does."
---

Contents: P1 Test-First Development, P2 Spec-First Execution, P3 Definition of Done, P4 Continuous Quality Feedback, P5 Shift-Left Quality, P6 Leave it Better Than You Found it, P7 Short-Lived Branches with AI+Human Review, P8 Architecture Decision Records.

The rest of the Process tenets of the Prickles canon, v4.0.0. Each tenet's first paragraph is its rule, in the always-loaded Prickles entry. What follows binds you exactly as that rule does.

## Prickles P1: Test-First Development

In typed languages, the type is the first test. Define the signature, leave the body as a hole, let the compiler reject the inconsistencies the unit test would have caught, then write the test for the residue.

Test the public contract rather than the internals. The unit's contract is the test's contract. Mock cascades through private collaborators are the smell, not the rule.
…

Testing pillar

Loads by itself when Claude Code reads or edits a file that matches its paths.

.claude/rules/prickles-testing.md78 lines
---
paths:
  - "**/*.test.ts"
  - "**/*.test.tsx"
  - "**/*.spec.ts"
  - "**/*.spec.tsx"
  - "**/__tests__/**"
  - "**/*.feature"
---

Contents: TS1 Living Documentation, TS2 Specification by Example, TS3 Parameterised Scenarios, TS4 Real-Dependency E2E, TS5 Structural Assertions, TS6 Behaviour Testing, TS7 Test Isolation, TS8 One Concept Per Test.

The rest of the Testing tenets of the Prickles canon, v4.0.0. Each tenet's first paragraph is its rule, in the always-loaded Prickles entry. What follows binds you exactly as that rule does.

…

AI Collaboration pillar

A skill: the agent sees its description and reads the rest when the task needs it.

.claude/skills/prickles-ai/SKILL.md59 lines
---
name: prickles-ai
description: "Use at the start of every task in this repository, before relying on an API, library or version you have not checked, and before declaring the work done. Holds the rest of the Prickles AI Collaboration tenets, AI1 The Intern Pattern, AI2 Persistent Brief, AI3 Working Context, AI4 Verifiable Specs, AI5 Verify the API, AI6 Self-Review Pass, which bind you exactly as the always-loaded Prickles entry does."
---

Contents: AI1 The Intern Pattern, AI2 Persistent Brief, AI3 Working Context, AI4 Verifiable Specs, AI5 Verify the API, AI6 Self-Review Pass.

The rest of the AI Collaboration tenets of the Prickles canon, v4.0.0. Each tenet's first paragraph is its rule, in the always-loaded Prickles entry. What follows binds you exactly as that rule does.

## Prickles AI1: The Intern Pattern

Plan before you type. Use Plan Mode (Claude Code), spec-first prompts (Cursor), or a written outline checked into the PR description. The plan names files, decisions and the verification step.

Approve in writing. The plan is a contract. Approval is the gate. No edits until a human (or the orchestrator agent) signs off.
…

Tooling pillar

A skill: the agent sees its description and reads the rest when the task needs it.

.claude/skills/prickles-tooling/SKILL.md25 lines
---
name: prickles-tooling
description: "Use before configuring or changing a linter, formatter, type checker, duplication check or CI gate in this repository, and whenever one of them fails. Holds the rest of the Prickles Tooling tenets, TA1 Linter as Law, TA2 Duplication Detection, which bind you exactly as the always-loaded Prickles entry does."
---

Contents: TA1 Linter as Law, TA2 Duplication Detection.

The rest of the Tooling tenets of the Prickles canon, v4.0.0. Each tenet's first paragraph is its rule, in the always-loaded Prickles entry. What follows binds you exactly as that rule does.

## Prickles TA1: Linter as Law

Encode the limit before the violation. Line count, complexity, parameter count, file size, equality, return annotations, type-file naming, barrel files, import direction: all in `eslint.config.mjs` or its language equivalent.

When the linter trips, fix the code. Never disable the rule inline. The disable comment is the bug. The rule is doing its job.
…

Patterns pillar

Loads by itself when Claude Code reads or edits a file that matches its paths.

.claude/rules/prickles-patterns.md33 lines
---
paths:
  - "**/*.ts"
  - "**/*.tsx"
  - "**/*.mts"
  - "**/*.cts"
  - "**/*.vue"
  - "**/*.svelte"
  - "**/*.astro"
---

Contents: PT1 Patterns Are Vocabulary, PT3 Every Pattern Has a Failure Mode.

The rest of the Patterns tenets of the Prickles canon, v4.0.0. Each tenet's first paragraph is its rule, in the always-loaded Prickles entry. What follows binds you exactly as that rule does.
…

Review rules for Claude Code Review

Optional. Every tenet's rule, for Claude Code Review, which reads this file and not the rule files above.

REVIEW.md82 lines
# Prickles canon v4.0.0: review rules

Report a change that breaks any tenet below as a review finding, and name the tenet's ID. Each line is that tenet's rule: the first paragraph of its entry in the Prickles canon.

## Foundations (F1–F6)

- **F1 Single Responsibility Principle.** One obvious job per function, class, or module. When a second concern shows up in the same unit, peel it out so each piece has its own reason to change.
- **F2 Intention-Revealing Names.** Use names that answer why this exists and what it does in the domain vocabulary. If the signature does not hold the meaning, rename.
- **F3 Don't Repeat Yourself.** Give every fact, rule and decision in the system one home. If you find yourself typing the same logic, the same literal or the same shape twice, the second copy is a bug looking for a deadline.
- **F4 Simplicity.** Build for the requirement at hand, not the speculative future. No line of code is cheaper than the one you didn't write, and speculative generality is debt with no creditor.
- **F5 Self-Documenting Code.** Do not add comments that explain what the code does. If a reader needs help, improve names, extract functions, add types, or add tests until the code tells the story.
- **F6 Encapsulation.** Hide the inside of your code. Callers should only call methods: never read or change fields directly. The method names are the contract. The body of the code is private and free to change.

## Architecture (A1–A11)
…
§4

Download

Pick a language, an agent and a layout. The pack holds the lint config for that language, the rule files that agent reads, and PRICKLES-SETUP.md with the install steps for that agent. This is version 4.0.0: see what changed in the changelog.

Step 1. Pick the language

Step 2. Pick your agent

Step 3. Pick the layout

A short entry with every tenet's rule is always loaded. The rest of each pillar loads when the work needs it: by file pattern where the agent supports it, otherwise as a skill or when the entry sends the agent to it.

Part of this pack is hidden

This pack includes .claude. Many file managers hide a file or folder whose name starts with a dot, so the unzipped pack can look as if something is missing. It is all there. To see it:

  • Windows: in File Explorer, choose View → Show → Hidden items.
  • macOS: in Finder, press Command + Shift + . (full stop).
  • Linux: in most file managers, press Ctrl + H.