---
name: Coding Standards
slug: coding-standards-2
category: Writing
description: Coding Standards creates and updates project-specific conventions, rules, and guidelines. Use it when you need to draft, convert, or revise standards for a codebase.
github: "https://github.com/testdouble/han/tree/main/han-coding/skills/coding-standard"
language: Shell
stars: 253
forks: 22
install: "npx degit https://github.com/testdouble/han/tree/main/han-coding/skills/coding-standard ~/.claude/skills/coding-standard"
installs_to: ~/.claude/skills/coding-standard
source_path: han-coding/skills/coding-standard/SKILL.md
collection_size: 25
category_size: 1060
collection_url: "https://dirskills.com/collections/testdouble/han"
added: 2026-09-02T05:20:50.737Z
last_synced: 2026-09-02T05:20:50.737Z
canonical_url: "https://dirskills.com/skills/coding-standards-2"
---

# Coding Standards

Coding Standards creates and updates project-specific conventions, rules, and guidelines. Use it when you need to draft, convert, or revise standards for a codebase.

**Install:**

```bash
npx degit https://github.com/testdouble/han/tree/main/han-coding/skills/coding-standard ~/.claude/skills/coding-standard
```

## README

## Project Context

- CLAUDE.md: !`find . -maxdepth 1 -name "CLAUDE.md" -type f`
- AGENTS.md: !`find . -maxdepth 1 -name "AGENTS.md" -type f`
- project-discovery.md: !`find . -maxdepth 3 -name "project-discovery.md" -type f`
- Rules directory: !`find . -maxdepth 4 -type d -path "*/.claude/rules/coding-standards"`
- personal config directory: !`bash "${CLAUDE_PLUGIN_ROOT}/scripts/han-config-dir.sh" 2>/dev/null || echo "$HOME/.claude"`
- project .han/config.md: !`cat .han/config.md 2>/dev/null || echo ""`

As your first action, use the Read tool on `.han/config.md` inside the `personal config directory` path above. A read
that returns no file is no personal configuration: continue silently. When that file or the `project .han/config.md`
probe supplies content, apply it per [config-rule.md](../../references/config-rule.md), which governs precedence
between the two files, relative-path resolution, and what to do with a file that reads but cannot be used.

## Step 1: Determine Mode

Determine which mode to operate in based on the user's request:

| Mode                | When                                                      | Initial Status | Then                                        |
| ------------------- | --------------------------------------------------------- | -------------- | ------------------------------------------- |
| Creating new        | Building a coding standard from scratch                   | `proposed`     | → Step 2                                    |
| Converting existing | User provides an existing document (ADR, etc.) to convert | `accepted`     | → Step 2                                    |
| Updating existing   | Modifying an existing coding standard                     | —              | Read the existing coding standard, → Step 3 |

## Step 2: Evaluate Appropriateness

Coding standard documents are **not a replacement for automated tooling**. Before proceeding, evaluate whether the
proposed coding standard falls into one of these categories:

- Conventions that should be enforced by linters or formatters (variable naming, indentation, whitespace, import
  ordering, bracket placement, line length, semicolons)
- Common language conventions that are well-known or easily discoverable from the language's own documentation and
  community norms (type declaration style, etc.)

If the proposed coding standard falls into one of these categories:

1. Warn the user that this is typically handled by automated tooling or is a well-known language convention, and that
   documenting it adds maintenance burden without value. Recommend configuring tooling instead.
2. Ask the user whether they still want to proceed
3. If the user declines, stop — the skill is done

If the proposed coding standard does not fall into these categories, proceed to the YAGNI check below.

### YAGNI check

Apply the evidence-based YAGNI rule from [../../references/yagni-rule.md](../../references/yagni-rule.md) alongside the
companion evidence rule in [../../references/evidence-rule.md](../../references/evidence-rule.md). A coding standard is
worth writing only when the project actually does the thing the standard governs _today_ and the standard solves a real,
concrete problem the team is currently hitting. Standards about patterns the project doesn't use yet, "for future
flexibility", "best practice says we should…", or symmetry with other standards ("we have one for backend, so we should
have one for frontend" when the frontend codebase is a single file) are YAGNI candidates. Acceptable evidence the
standard is needed _now_:

- The pattern the standard governs is actively used in the codebase today (cite at least three examples), and
  inconsistency between examples is causing real friction (review churn, bugs, onboarding cost).
- A documented incident or recurring code-review finding the standard would prevent.
- A regulatory or compliance rule the project actually falls under that requires the convention.
- A user-described need ("I keep having to remind people about X").

If no accepted evidence applies, recommend deferring the standard with the trigger that would justify writing it (a
third instance of the pattern lands, a real incident occurs, a recurring review finding accumulates). Surface the
recommendation to the user with the override option.

## Step 3: Discover Project Structure

1. **Retrieve project config:** Resolve project config: read CLAUDE.md's `## Project Discovery` section for docs and
   coding-standards directories; fall back to project-discovery.md; fall back to Glob defaults (`docs/`,
   `docs/coding-standards/`). Continue without any keys that remain unfound.

2. **Determine the coding standards directory:**
   - If a coding standards directory was found, use it
   - If only a docs directory was found, create `{docs-dir}/coding-standards/`
   - If neither was found, create `docs/coding-standards/`

3. **Enumerate existing coding standards:** If a coding standards directory was found, use Glob to enumerate existing
   `.md` files in that directory.

4. **Check existing coding standard format:** If existing coding standards were found via Glob, read one to understand
   the project's existing format. If it uses a different format than the template at
   [template.md](./references/template.md), ask the user whether to match the existing format or use this skill's
   template.

5. **Discover the filename hierarchy taxonomy:** Coding standards are organized by a one- or two-level hierarchy encoded
   in the filename so related standards sort together in a directory listing. Discover the taxonomy that applies to
   _this_ project — never hardcode it.
   - **From existing filenames:** If existing standards were enumerated, parse their filenames to extract the leading
     hierarchy segments already in use (e.g., `svelte-component-naming.md` → top-level `svelte`;
     `svelte-stores-state-shape.md` → top-level `svelte`, second-level `stores`). Build a list of top-level prefixes and
     known second-level prefixes per top-level.
   - **From project context:** Read CLAUDE.md and project-discovery.md (paths from project context above) to identify
     the project's languages, frameworks, runtimes, and major subsystems. Each of these is a candidate top-level
     hierarchy (e.g., `svelte`, `rails`, `postgres`, `terraform`, `api`, `worker`).
   - **Carry forward to Step 6:** the discovered top-level prefixes (existing + candidate) and any second-level prefixes
     already in use under each.

6. **Discover the project's primary file-type globs and group them into index-file buckets.** The `paths:` frontmatter
   in Step 6 needs file globs scoped to the languages and directories the new standard governs. The Step 7 integration
   then routes the new standard into one or more **per-file-type index files** under `.claude/rules/coding-standards/`,
   where each index file owns a single file-type bucket (for example, `svelte.md` owns `**/*.svelte`; `typescript.md`
   owns `**/*.ts` and `**/*.tsx`; `ruby.md` owns `**/*.rb` and `app/**/*.rb`). Build the candidate glob set and its
   bucket grouping now so Steps 6 and 7 have them on hand.
   - **From CLAUDE.md and project-discovery.md:** extract every language, file extension, and major source directory the
     project actually uses (e.g., `**/*.go`, `**/*.ts`, `**/*.tsx`, `**/*.py`, `**/*.rb`, `app/**/*.rb`,
     `services/**/*.go`).
   - **From existing standards' `paths:` frontmatter:** if any existing standard already carries `paths:`, collect its
     globs as candidate glob prefixes — they reflect the project's accepted scoping vocabulary.
   - **From existing index files under `.claude/rules/coding-standards/`:** if the rules directory was found in the
     project context, enumerate the index files already present and read each one's `paths:` frontmatter. Each existing
     file defines an established bucket; reuse it rather than introducing a parallel bucket for the same file type.
   - **Fallback:** if no source yields globs, glob the project root for the dominant file extensions (`**/*.{ext}` for
     each extension seen in more than a handful of files) and surface what you found.
   - **Group into buckets:** organize the resolved candidate glob set into file-type buckets, one per index file. Reuse
     an existing bucket whenever one fits; introduce a new bucket only when no existing index file's `paths:` covers the
     new glob. Name new buckets after the language, framework, or subsystem they cover (e.g., `svelte`, `typescript`,
     `ruby`, `sql`) — the bucket name becomes the index file's filename in Step 7.
   - **Carry forward to Steps 6 and 7:** the candidate glob set grouped by bucket, plus the list of existing index files
     and the globs each one owns.

## Step 4: Gather Context

1. From the arguments and conversation, determine:
   - **Topic**: what the coding standard covers
   - **Scope**: which parts of the system it applies to
   - **Motivation**: why this needs to be a coding standard
2. If any of these are unclear, use `AskUserQuestion` to clarify before writing

### Launch evidence-gathering agents

Skip these agents when the user has already provided full Correct-usage examples and conflicting-pattern evidence.
Otherwise, launch both in parallel — one finds what the codebase already does, the other checks what the project has
already documented. Include the topic, scope, and docs/coding-standards directories from Step 3.

1. **Launch han-core:codebase-explorer agent (implementation patterns)** — prompt: "Explore the codebase for existing
   implementations related to {topic} across {scope}. Return concrete places that illustrate the convention in practice
   (Correct-usage candidates), places that violate or contradict the convention (What-to-avoid candidates), and any
   places where the convention is applied inconsistently across the codebase. For each place, return a file path, a line
   range, and one or more greppable durable anchors — read `${CLAUDE_SKILL_DIR}/references/durable-references.md` and
   follow its Rules 1 and 2 to derive them; where Rule 2 reaches escalation, return the place flagged for engineer
   review instead of an anchor. Focus on real files; do not invent examples."

2. **Launch han-core:codebase-explorer agent (standards and ADRs)** — prompt: "Explore {docs-directory} and
   {coding-standards-directory} for existing coding standards, ADRs, or project docs that touch {topic} across {scope}.
   Return: any standards or ADRs that already cover this topic (in full or in part), cross-references that the new
   standard will need to link — each as a document path plus a stable section heading — and any contradictions between
   existing docs that the new standard will need to resolve or cite."

After both agents complete, merge their findings into a context block:

- **Correct-usage candidates** — durable anchor(s), plus the line range (Step 6 drops it unless a house style keeps it)
  — for Step 6
- **What-to-avoid candidates** — same pairing — for Step 6
- **Flagged candidates** — places the rule could not cleanly anchor, carried as engineer-review items for Step 6; no
  reference is emitted for one without engineer input
- **Inconsistency notes** — areas where the convention is applied unevenly (these become Rationale material, not
  examples)
- **Existing-doc cross-references** (document path plus stable section heading) for Step 7

## Step 5: Convert Source Document (skip if creating new or updating)

When converting an existing document into a coding standard:

1. Read the source document
2. Map sections to coding standard sections using the mapping at
   [adr-conversion-mapping.md](./references/adr-conversion-mapping.md)
3. **If the source document is fully subsumed:** delete it and update references (search `CLAUDE.md`, `AGENTS.md`, and
   other markdown files)
4. **If the source document retains useful content:** add a link to the new coding standard in the source document and
   remove migrated sections

## Step 6: Write the Coding Standard

Before writing, invoke `han-communication:readability-guidance` to source the shared readability standard into your
context, then apply it as you write the standard's prose (Purpose, Rationale, when-to-apply, when-not-to-apply, and
example commentary), holding the named audience: the engineer who must follow the standard. The frame governs how a fact
is said, never whether a required fact appears — keep the exact rules, thresholds, and anchors the standard commits to.

Read the **durable-reference rule** in [durable-references.md](./references/durable-references.md) and apply it
throughout this step — this is the rule's **authoring mode** — all rules apply. For any candidate Step 4 flagged for
engineer review — or any example you cannot cleanly anchor yourself — surface it to the engineer with a recommended
resolution rather than emitting a coarse or anchorless reference; do not silently resolve it.

1. Copy the template from [template.md](./references/template.md)
2. **File name:** `{top-level}[-{second-level}]-{hyphenated-name}.md` — a one- or two-level hierarchy prefix followed by
   the standard's specific name. The hierarchy must come from the taxonomy discovered in Step 3.5, never invented or
   hardcoded.
   - **Top-level (required):** the highest-level grouping the standard belongs to (e.g., `svelte`, `rails`, `postgres`,
     `api`). Reuse an existing top-level prefix from Step 3.5 when one fits; only introduce a new top-level when no
     existing prefix applies, and prefer one that matches a language, framework, or subsystem already named in CLAUDE.md
     or project-discovery.md.
   - **Second-level (optional):** add only when the top-level has — or will plausibly grow — multiple standards that
     benefit from a sub-grouping (e.g., `svelte-stores-…`, `svelte-components-…`). Reuse an existing second-level prefix
     from Step 3.5 when one fits. Skip the second level when the standard is the only one (or one of a few) under its
     top-level.
   - **Hyphenated-name (required):** the specific topic of this standard, hyphenated, distinct from the hierarchy
     prefix.
   - If the discovered taxonomy offers more than one reasonable placement, ask the user to choose before writing.
3. **Location:** place in the directory determined in Step 3
4. **Fill in metadata:**
   - **Status**: per Step 1 mode (`proposed` for new, `accepted` for converted)
   - **Applies To**: a membership criterion for entities governed by this standard, per durable-reference Rule 3.
   - **Date Created / Last Updated**: current date and time
5. **Propose the `paths:` glob list and get user approval.** The `paths:` field in the YAML frontmatter is the canonical
   declaration of which file globs the standard governs. Step 7 uses each glob to route the new standard into one or
   more per-file-type **index files** under `.claude/rules/coding-standards/` — the standard itself is never loaded
   directly as a path-scoped rule. The index files are what Claude Code loads via
   [Claude Code path-scoped rules](https://code.claude.com/docs/en/memory), and they then point Claude at this standard
   on demand. Cross-cutting standards whose `paths:` span multiple file-type buckets get listed in each matching index.
   - **Build the candidate list** from the Applies To text and Scope section of this standard, intersected with the
     project file-type globs discovered in Step 3.6. Scope a glob no broader than the standard actually governs — if the
     standard applies only to Svelte stores, prefer `src/**/stores/**/*.ts` over `**/*.ts`.
   - **Surface the proposal to the user** with `AskUserQuestion` (or as a recommendation when running unattended). Quote
     the Applies To text or scope clause that justifies each glob; mark inferred globs as `(inferred)`. Name the
     index-file bucket(s) each glob will be routed into in Step 7 so the user can see the integration consequence. Do
     not write the file until the user confirms or proposes a substitute.
   - **YAML rule:** each glob must be double-quoted (characters like `*`, `{`, `[` are YAML-significant and fail to
     parse unquoted). Globs follow Claude Code's standard glob syntax (`**`, `*`, `?`, `{a,b}`).
6. **Write the YAML frontmatter at the top of the file.** Place a `---` block before the `# {Title}` heading containing
   at minimum the approved `paths:` list. Example:
   ```
   ---
   paths:
     - "**/*.go"
     - "internal/services/**/*.go"
   ---
   ```
   When updating an existing standard (Step 1 mode = "Updating existing"), preserve every existing frontmatter key —
   only ADD or REPLACE `paths:`. Never strip `name`, `description`, `type`, or any other key the file already carries.
7. **Fill each template section** with real code examples from the codebase (found in Step 4)
8. **Code fence language identifiers** must match the project's actual languages
9. **For cross-cutting coding standards:** include examples from each system area, label by area not language, set
   Applies To to list all areas, and propose a `paths:` list that includes one glob per area (e.g., `"app/**/*.rb"` plus
   `"services/**/*.go"`)
10. **If no real code examples exist yet** (coding standard for a pattern not yet implemented): label examples as
    "Proposed pattern" and note this in the Introduction

## Step 7: Integration

The standard is consumed by Claude Code through a small set of per-file-type **index files** under
`.claude/rules/coding-standards/`. Each index file is itself a
[path-scoped rule](https://code.claude.com/docs/en/memory) that carries `paths:` frontmatter for one file type (or a
closely-related group), a brief load-on-demand instruction paragraph, and a list of entries pointing to the canonical
standards in the project's coding-standards directory. When Claude Code reads a file matching an index file's globs,
Claude loads only that small index, then decides which (if any) of the listed standards to open with the Read tool. The
full text of a standard is never loaded automatically. This replaces the prior one-symlink-per-standard layout, which
forced every standard whose `paths:` matched the current file into context at once. **Do not add the new standard as an
enumerated link in `CLAUDE.md` (or `AGENTS.md`).** Rules are discovered through the `.claude/rules/` surface, not
through the memory file, and enumerating them in the memory file is the failure mode this integration replaces.

1. **Determine which index file(s) the new standard belongs in.** Using the buckets carried forward from Step 3.6, map
   each glob in the standard's approved `paths:` to a bucket. The set of matching buckets is the set of index files the
   standard will be listed in. A standard whose `paths:` spans multiple buckets (a cross-cutting standard, e.g.,
   `"app/**/*.rb"` plus `"services/**/*.go"`) will be listed in each matching index — the canonical standards file is
   still only ever in one place; only the index entries are repeated.

2. **Ensure `.claude/rules/coding-standards/` exists.** Run `mkdir -p .claude/rules/coding-standards`.

3. **For each matching index file, create or update it.**

   - **If the index file does not exist yet**, copy the template at
     [index-file-template.md](./references/index-file-template.md) to `.claude/rules/coding-standards/{bucket-name}.md`
     and fill it in:
     - Replace the placeholder globs in `paths:` with the bucket's globs (each double-quoted; see the YAML rule in Step
       6.5).
     - Replace `{File-type}` in the heading with the bucket name (e.g., `Svelte`, `TypeScript`, `Ruby`). Use the
       capitalization that matches the language/framework's own conventions.
     - Leave the entire instruction paragraph (everything between the heading and the `## Available standards` heading)
       verbatim. It is what tells Claude to make a relevance decision before opening any standard.
     - Replace
