BeClaude

inherit-legacy-style

New
GitHub TrendingGeneralby linsywu

Legacy-project style inheritance skill. Use when the user types /inherit-legacy-style, or when onboarding an AI coding agent onto a hand-written legacy project and you need to prevent "style drift" (the model imposing its pretrained mainstream idioms onto the project). Language- and framework-agnostic — it aligns only the meta-architecture, not surface syntax. Once run, it becomes a behavioral constraint on all subsequent coding tasks. Do NOT use for pure research or one-off questions unrelated to code-style alignment.

First seen 6/1/2026

Overview

Inherit Legacy Style

Overview

When an AI coding agent is dropped onto a hand-written legacy project, the model's pretraining bias makes it impose its own "mainstream" idioms, causing Style Drift: two competing list-refresh patterns in one codebase, inconsistent naming, duplicated utility functions.

This skill fixes that. It is fully language- and framework-agnostic — it does not judge syntax sugar; it extracts and aligns the project's meta-architecture along four dimensions, then crystallizes the consensus into a root-level .ai-style-rules.md that acts as a binding constraint on subsequent coding.

Core principle: reuse the legacy exemplar over free improvisation. When a legacy pattern can be reused pixel-for-pixel, never inject the model's own preferred style.

Output Language Policy (applies to every produced artifact)

The skill's own instructions are in English, but everything this skill produces for the user must mirror the language the user is communicating in:

  • .ai-style-rules.md content, the CLAUDE.md hook line, grilling questions, the strength-of-enforcement prompt, status reports, and the evolution log — all written in the user's language (e.g. Chinese if the user writes in Chinese, English if in English).
  • Detect the user's language from their messages in the conversation. When ambiguous, default to English and proceed.
  • Code-level tokens (identifiers, file paths, JSON keys, the exemplar names) stay verbatim regardless of language.

Step 0 — Adaptive Mode Detection (zero-argument trigger)

On /inherit-legacy-style, the first action must be a silent check for .ai-style-rules.md at the project root:

code
if .ai-style-rules.md absent  →  Branch A: [First-time · Full-Scan mode]
if .ai-style-rules.md present →  Branch B: [Evolution · Incremental-Sniff mode]

Use Glob or ls. Announce the chosen mode in one line, then execute that branch directly — do not ask the user to pick a mode.


Branch A — First-time · Full-Scan mode

Use Glob to locate sources, Grep to search patterns, Read to study exemplars, and extract the four-dimension implicit rules.

Measure scale first, then pick a scan tier (Scale-Adaptive)

Scanning is not one-size-fits-all sampling — sampling starves small projects (too few samples, distorted frequencies); full traversal blows up large repos (token/time overflow). First measure scale:

bash
git ls-files 2>/dev/null | grep -cE '\.(js|ts|jsx|tsx|vue|py|go|rs|java|kt|rb|php|cs|swift|c|cpp|h)$'
# Non-Git fallback: find . -type f \( -name '*.js' -o -name '*.vue' ... \) -not -path '*/node_modules/*' | wc -l

Pick a tier by source-file count:

TierSource filesStrategy
Small≲ 50Full close-read. Read every core source; no sampling. When frequency base is too low (e.g. "3 vs 2") to auto-decide, escalate to grilling — never guess the majority.
Medium50 – 500Layered. Infra layer (apis/utils/store/config) read fully; business layer (views/pages/handlers) sample 2-3 exemplars per dimension by frequency + recency (Git).
Large≳ 500Strict sampling + budget cap. Read only files touched in the last N Git changes + the top 2-3 highest-frequency exemplars per dimension; cap file/read count, locate via --stat summary before Read.

In every tier, evidence priority is fixed: frequency > recency (Git) > human-written (avoid generated code / vendor). Tell the user the chosen tier in one line (e.g. "833 source files → Large project, strict sampling").

The Four Scan Dimensions

Examples span frontend / backend / CLI to show "cross-stack, meta-architecture only" — map to the project's actual stack; do not force irrelevant examples.

  1. File Anatomy — the in-file declaration order. Frontend: import → types/consts → main → helpers → export; Backend: package/imports → consts → struct/types → constructors → methods → private helpers; CLI: flag defs → config load → main flow → subcommands. Record the actual template.
  1. State & Control Flow — control-variable naming and combinations in common high-frequency logic. Frontend: async tri-state loading/error/data, pagination pageIndex/pageSize/total; Backend: pagination offset/limit vs page/size, transaction boundaries, context propagation; CLI: exit-code conventions, --verbose/--dry-run flag naming. Record naming + combination.
  1. Infrastructure — where high-frequency cross-cutting operations are reused, and how named. Frontend: where interceptors / date-money formatters live; Backend: where DB conns/middleware/loggers are initialized, where error-code constants are defined; CLI: location of config parsing / output formatting utilities.
  1. Error Handling — exception preference (try/catch vs global interceptor vs Result/error return vs panic/recover) and null-check habits (optional chaining, early return, default fallback, if err != nil).

Conflict handling

If the scan finds the project self-contradicting (two list-refresh patterns, two naming styles), do not self-arbitrate — go to [Grilling & Alignment] below, one at a time.

Output (first-time creation of .ai-style-rules.md)

Once there are no conflicts (or all are resolved), create from scratch the root .ai-style-rules.md with three mandatory sections (write content in the user's language per the Output Language Policy):

  • [Golden Files] — real exemplar file paths per dimension, each annotated with what it demonstrates.
  • [Naming & State-Control Rules] — concrete, checkable rules distilled from the four dimensions.
  • [DONTs] — bad smells that exist but must not propagate (deprecated idioms, the arbitrated-away alternative).

Template: `reference/rules-template.md`.

Critical: write the persistent hook (else the rules expire next turn)

.ai-style-rules.md is not auto-loaded by future sessions. Right after creating it, install the hook so it becomes a per-turn constraint (see Step 5). Do this before reporting.


Branch B — Evolution · Incremental-Sniff mode

Refuse to re-scan in full. Only sniff whether the human's recent changes introduced a new style or new utility that differs from the recorded rules.

Sniff steps

  1. Read the existing .ai-style-rules.md into context. If its header records the last-scan commit fingerprint, run git diff <last_hash> HEAD --stat to pinpoint the delta precisely.
  2. Read the human's recent changes (try in order of availability):

``bash git status git log -3 --stat # last 3 commits (read --stat summary first to locate touched files) git diff HEAD~3 HEAD # only inspect suspect files on demand; do not dump the full diff ` **Oversized-diff fallback** (e.g. just merged hundreds of files): read only the --stat summary + sample the few largest source changes; do not load the whole diff. Non-Git repo or command failure → fall back to most-recently-modified sources (ls -lt`).

  1. Compare: does the new code show patterns / utilities / idioms that are unrecorded or in conflict with the existing rules?

Conflict handling

Conflict found → go to [Grilling & Alignment], one at a time. No conflict → tell the user "no style drift detected, rules unchanged" and stop.

Output (append, never overwrite)

Never overwrite or erase old rules. Append an evolution log at the end of .ai-style-rules.md (in the user's language):

markdown
### [YYYY-MM-DD] Style Evolution Log
- New consensus: … (source: path, user chose option N)
- New exemplar / utility: …

Use the real current date (date +%F).


Grilling & Alignment — shared by both branches

Pass the signal threshold before interrupting the user (noise reduction)

Not every difference deserves a question. On finding two styles, assess signal strength first to avoid spamming the user:

  • Weak signal → no grilling, auto-suppress: when one side is overwhelmingly minor (minority < 5% and absolute count < 10), take the majority as the rule, record the minority in DONTs, and just mention it in one line in the final report.

- Example: pageIndex(843) vs pageNum(8) → auto-suppress; library choice moment(1) vs dayjs(2) → base too small, non-core, skip entirely.

  • Strong signal → must grill: the two styles are comparable (e.g. 6:4), or despite skew it is a semantic fork on a core dimension (two incompatible list-refresh mechanisms, two error-handling paradigms).
  • Small-project exception: when sources ≲ 50, the frequency base is inherently low — "3 vs 2" is not a majority signal, so downgrade to grilling; do not auto-arbitrate.

The threshold is heuristic; when unsure, lean toward asking rather than guessing.

When grilling, enforce strict one-at-a-time interaction

Once confirmed a strong signal, enforce the one-soldier grilling protocol:

  1. One soldier: raise exactly one conflict at a time. Never stack multiple questions.
  2. Fixed question format (in the user's language):

> 📄 Evidence in code: at pathA style X is used, while at pathB (or in existing rules) style Y is used. > ⚠️ Risk: mixing both in new features will fracture the project's style. > ❓ Choose: which should subsequent development follow? Reply with a number — > 1 follow X 2 follow Y 3 this is the latest evolution, update the rules 4 I have a new rule: [input]

Prefer presenting the four options via the AskUserQuestion tool.

  1. Suspend and wait: only after an explicit answer is received and recorded may you proceed to the next conflict. Multiple conflicts → serial, one by one.

Step 5 — Runtime Enforcement Hook

⚠️ Core insight: the instructions loaded this turn evaporate when the conversation ends or context is compacted. Relying on "I'll remember to load the rules" is unreliable — the constraint dies in a new session. A real constraint must be written where Claude reads it automatically every turn.

5.1 Let the user choose enforcement strength, then hook accordingly (mandatory after first-time creation)

Enforcement strength is the user's call — do not default it for them. After creating the rules, first ask via AskUserQuestion (one of three, phrased in the user's language):

.ai-style-rules.md is created. How strongly should subsequent coding obey it?

- 1 Soft hook (recommended · sufficient): write into the project CLAUDE.md, auto-loaded every session. Easy, but the model can theoretically bypass it.

- 2 Hard hook (mechanical enforcement): soft hook + a PreToolUse[Write|Edit] hook that injects a rule reminder before every file write, unbypassable. Modifies settings.json.

- 3 No hook for now: just keep the rules file; I'll @-reference it manually.

Options 1 and 2 both do the soft hook first — attach the rules to the project root CLAUDE.md (auto-injected every session):

  1. Check for a root CLAUDE.md (Glob/ls).
  2. Exists: Edit to append one reference line in a prominent place, never overwriting:

``markdown > 📐 Read @.ai-style-rules.md before coding — obey its naming/state/infra rules, avoid the DONTs. `` (Write this line in the user's language.)

  1. Absent: Write a minimal CLAUDE.md containing only that line.

Only option 2 adds the hard hook — configure a PreToolUse hook. Key: do NOT `cat` the full file (~1000 extra tokens per write); the content is already loaded once per session via the CLAUDE.md @ reference, so the hook only injects a ~20-token reminder. Prefer invoking the update-config skill to write into settings.json:

json
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Write|Edit|MultiEdit",
        "hooks": [
          { "type": "command",
            "command": "echo 'Reminder: obey .ai-style-rules.md before this write (naming/state/infra rules + DONTs).'" }
        ]
      }
    ]
  }
}

Use PreToolUse[Write|Edit|MultiEdit] not UserPromptSubmit: the former fires only when actually writing a file (zero cost on reads/chat); the latter burns tokens every turn. After writing, tell the user it's set and a new session / reload fully activates it.

Option 3: skip hooks; just tell the user the rules live in .ai-style-rules.md and to @-reference them when needed.

Without the 5.1 hook (option 1/2), this skill is a one-shot scanner, betraying its "workflow / binding constraint" identity.

5.2 Per-turn compliance declaration (runtime behavior)

Whenever .ai-style-rules.md (loaded via 5.1's CLAUDE.md reference) is in context, any write/edit/refactor task must explicitly load it as the first thought and open the reasoning with a compliance declaration, e.g. (in the user's language):

"Loaded .ai-style-rules.md. This round I will reuse the state-control pattern from exemplar X pixel-for-pixel, keep existing naming, and avoid the DONTs."

Two constraints:

  • Reuse structure and naming, but do not copy bugs: if the exemplar has obvious dead code / defects (duplicate return, empty catch), do not replicate them — flag to the user instead.
  • If the new task itself introduces a requirement conflicting with the rules, go back to [Grilling & Alignment], then continue.

Checklist (hard rules)

  • [ ] Step 0 silently detects file presence, auto-branches, never asks the user to pick a mode.
  • [ ] Branch A measures scale via git ls-files | wc -l first, picks Small/Medium/Large tier (Small=full read, Large=sampling+budget cap), announces the tier.
  • [ ] Scan aligns meta-architecture only, never judges syntax; examples map to the project's actual stack.
  • [ ] Conflicts pass the signal threshold first: weak → auto-suppress into DONTs, strong → grill; grill one at a time, fixed four-option format, suspend and wait.
  • [ ] First-time = create three sections from scratch; incremental = append evolution log at end, never overwrite.
  • [ ] After creating rules, run 5.1: first AskUserQuestion for enforcement strength (soft/hard/none); soft → write CLAUDE.md; hard → also call update-config for a PreToolUse hook (inject a one-line reminder, never cat the full file).
  • [ ] Every later coding turn opens with a compliance declaration; reuse structure but never copy the exemplar's bugs / dead code.
  • [ ] All user-facing artifacts (rules file, hook line, questions, reports, log) are written in the user's language; only the skill's own instructions are English.

Install & Usage

1
Create the agents directory
mkdir -p .claude/agents
2
Save the agent file

Add the configuration to .claude/agents/inherit-legacy-style.md

3
Invoke with @agent-name
@inherit-legacy-style
View source on GitHub
agent

Security Audits

LicenseUnknownSourceWarnRepositoryPass

Frequently Asked Questions

What is inherit-legacy-style?

Legacy-project style inheritance skill. Use when the user types /inherit-legacy-style, or when onboarding an AI coding agent onto a hand-written legacy project and you need to prevent "style drift" (the model imposing its pretrained mainstream idioms onto the project). Language- and framework-agnostic — it aligns only the meta-architecture, not surface syntax. Once run, it becomes a behavioral constraint on all subsequent coding tasks. Do NOT use for pure research or one-off questions unrelated to code-style alignment.

How to install inherit-legacy-style?

To install inherit-legacy-style: create the agents directory (mkdir -p .claude/agents), then add the config to .claude/agents/inherit-legacy-style.md. Finally, @inherit-legacy-style in Claude Code.

What is inherit-legacy-style best for?

inherit-legacy-style is a agent categorized under General. It is designed for: agent. Created by linsywu.