convention-learner

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Convention Learner

规范学习器

Core Principles

核心原则

  1. Observe before enforcing — Never impose conventions without first analyzing the existing codebase. A project with 200
    internal sealed class
    handlers should not get a new
    public class
    handler. Detect first, then match.
  2. Project conventions override generic rules — If the project uses
    *Service
    instead of
    *Handler
    , follow the project's convention even if the kit default is different. Explicit
    .editorconfig
    and
    Directory.Build.props
    rules always win.
  3. Use MCP tools for analysis
    get_public_api
    reveals naming patterns,
    get_project_graph
    shows structure conventions,
    detect_antipatterns
    tracks quality trends. Tools provide objective data; file reads provide confirmation.
  4. Document findings — After detecting conventions, suggest adding them to the project's CLAUDE.md. Undocumented conventions are lost when the original developers leave.
  5. Consistency over perfection — A project with consistent
    snake_case
    database columns is better than a project with half
    snake_case
    and half
    PascalCase
    . Match the existing pattern, even if another convention is theoretically superior.
  1. 先观察分析,再强制执行——在未分析现有代码库的情况下,绝不强加规范。一个包含200个
    internal sealed class
    处理器的项目,不应新增
    public class
    处理器。先检测,再匹配。
  2. 项目规范优先于通用规则——如果项目使用
    *Service
    而非
    *Handler
    ,则遵循项目规范,即便工具包默认规则不同。显式的
    .editorconfig
    Directory.Build.props
    规则始终优先。
  3. 使用MCP工具进行分析——
    get_public_api
    可揭示命名模式,
    get_project_graph
    展示结构规范,
    detect_antipatterns
    跟踪质量趋势。工具提供客观数据;文件读取用于验证。
  4. 记录检测结果——检测到规范后,建议将其添加到项目的CLAUDE.md中。未记录的规范会在原始开发人员离职后丢失。
  5. 一致性优先于完美——数据库列统一使用
    snake_case
    的项目,比一半用
    snake_case
    、一半用
    PascalCase
    的项目更好。匹配现有模式,即便另一种规范理论上更优。

Patterns

模式

Convention Detection Flow

规范检测流程

Systematic analysis to understand a project's coding conventions. Run this when joining an existing project or before generating new code.
Step 1: Project Structure Analysis
→ get_project_graph
  Detect:
  - Project naming: PascalCase? Dots? (MyApp.Domain vs Domain)
  - Layer organization: by layer (Domain/Application/Infrastructure) or by feature?
  - Test project naming: *.Tests, *.UnitTests, *.IntegrationTests?
  - Shared project: Common/, Shared/, BuildingBlocks/?
Step 2: Type Naming Patterns
→ get_public_api (on 3-5 key types across different layers)
  Detect:
  - Class modifiers: sealed? internal? internal sealed?
  - Interface prefix: I* (standard) or no prefix?
  - Suffix conventions: Handler, Service, Repository, Validator, Endpoint?
  - Record usage: for DTOs? for value objects? for commands/queries?
  - Primary constructor usage: consistently? selectively?
Step 3: Folder Structure Patterns Scan the file system for structural conventions:
  • Feature folders:
    Features/{FeatureName}/
    with all files together?
  • Layer folders:
    Controllers/
    ,
    Services/
    ,
    Repositories/
    separate?
  • Shared patterns:
    Common/
    ,
    Extensions/
    ,
    Middleware/
    ?
  • Configuration location: root?
    Config/
    folder?
    Infrastructure/
    ?
Step 4: Configuration Detection Check for explicit convention enforcers:
→ Look for Directory.Build.props
  - TreatWarningsAsErrors?
  - Nullable enabled globally?
  - ImplicitUsings?
  - AnalysisLevel?

→ Look for .editorconfig
  - Naming rules: camelCase fields? _prefixed privates?
  - Code style: var preferences, expression bodies, using placement

→ Look for global.json
  - SDK version pinned?
  - Roll-forward policy?
Step 5: Build Convention Summary Compile findings into a structured summary:
markdown
undefined
通过系统性分析了解项目的编码规范。加入现有项目或生成新代码前执行此流程。
步骤1:项目结构分析
→ get_project_graph
  检测内容:
  - 项目命名:PascalCase?带点?(MyApp.Domain vs Domain)
  - 层级组织:按层级(Domain/Application/Infrastructure)还是按功能?
  - 测试项目命名:*.Tests、*.UnitTests、*.IntegrationTests?
  - 共享项目:Common/、Shared/、BuildingBlocks/?
步骤2:类型命名模式
→ get_public_api(针对不同层级的3-5个核心类型)
  检测内容:
  - 类修饰符:sealed?internal?internal sealed?
  - 接口前缀:I*(标准)还是无前缀?
  - 后缀规范:Handler、Service、Repository、Validator、Endpoint?
  - Record使用:用于DTO?值对象?命令/查询?
  - 主构造函数使用:统一使用?选择性使用?
步骤3:文件夹结构模式 扫描文件系统以识别结构规范:
  • 功能文件夹:
    Features/{FeatureName}/
    下所有文件放在一起?
  • 层级文件夹:
    Controllers/
    Services/
    Repositories/
    分开?
  • 共享模式:
    Common/
    Extensions/
    Middleware/
  • 配置位置:根目录?
    Config/
    文件夹?
    Infrastructure/
步骤4:配置检测 检查显式的规范强制执行工具:
→ 查找Directory.Build.props
  - 是否将警告视为错误?
  - 是否全局启用Nullable?
  - 是否启用ImplicitUsings?
  - AnalysisLevel设置?

→ 查找.editorconfig
  - 命名规则:字段用camelCase?私有字段加_前缀?
  - 代码风格:var偏好、表达式体、using放置位置

→ 查找global.json
  - 是否固定SDK版本?
  - 向前兼容策略?
步骤5:构建规范摘要 将检测结果整理为结构化摘要:
markdown
undefined

Detected Conventions

检测到的规范

Naming

命名

  • Classes:
    internal sealed class
    (95% of handlers/services)
  • Suffixes: Handlers end in
    Handler
    , validators in
    Validator
  • Records: Used for DTOs and commands/queries
  • 类:
    internal sealed class
    (95%的处理器/服务)
  • 后缀:处理器以
    Handler
    结尾,验证器以
    Validator
    结尾
  • Record:用于DTO和命令/查询

Structure

结构

  • Architecture: Vertical Slice Architecture
  • Features:
    Features/{Name}/
    with command, handler, validator, endpoint in one file
  • 架构:垂直切片架构(Vertical Slice Architecture)
  • 功能:
    Features/{Name}/
    下将命令、处理器、验证器、端点放在同一文件中

Code Style

代码风格

  • Primary constructors: Used consistently for DI injection
  • Nullable: Enabled globally, no suppressions (
    !
    ) used
  • File-scoped namespaces: 100% consistent

Add categories as needed: EF Core (configurations, naming, migrations), Testing (framework, naming, fixtures), etc.
  • 主构造函数:统一用于依赖注入
  • Nullable:全局启用,未使用抑制符(
    !
  • 文件级命名空间:100%统一使用

根据需要添加分类:EF Core(配置、命名、迁移)、测试(框架、命名、夹具)等。

Convention Enforcement

规范强制执行

Apply detected conventions when generating new code or reviewing existing code.
When Generating Code: Match every detected pattern:
csharp
// If existing handlers are: internal sealed class + primary constructor
// Generate matching:
internal sealed class CreateProductHandler(AppDbContext db, TimeProvider clock)
{
    // Not: public class CreateProductHandler
    // Not: internal class CreateProductHandler (missing sealed)
}
csharp
// If existing DTOs are records with init properties
// Generate matching:
public record ProductResponse(Guid Id, string Name, decimal Price);
// Not: public class ProductResponse { public Guid Id { get; set; } }
When Reviewing Code: Flag deviations from detected conventions:
⚠️ Convention violation: CreateOrderHandler is `public class` but project convention
   is `internal sealed class` (detected in 12/12 existing handlers).
   Change to: internal sealed class CreateOrderHandler
Suggesting Enforcement Rules: After detecting conventions, suggest
.editorconfig
rules to enforce them automatically:
ini
undefined
生成新代码或审核现有代码时应用检测到的规范。
生成代码时: 匹配所有检测到的模式:
csharp
// 如果现有处理器为:internal sealed class + 主构造函数
// 生成匹配代码:
internal sealed class CreateProductHandler(AppDbContext db, TimeProvider clock)
{
    // 不要:public class CreateProductHandler
    // 不要:internal class CreateProductHandler(缺少sealed)
}
csharp
// 如果现有DTO为带init属性的record
// 生成匹配代码:
public record ProductResponse(Guid Id, string Name, decimal Price);
// 不要:public class ProductResponse { public Guid Id { get; set; } }
审核代码时: 标记与检测到的规范不符的内容:
⚠️ 规范违反:CreateOrderHandler为`public class`,但项目规范为`internal sealed class`(在12个现有处理器中检测到)。
   修改为:internal sealed class CreateOrderHandler
建议强制执行规则: 检测到规范后,建议添加
.editorconfig
规则以自动强制执行:
ini
undefined

Key .editorconfig rules to suggest based on detected conventions

根据检测到的规范建议添加的关键.editorconfig规则

dotnet_diagnostic.CA1852.severity = warning # Seal internal types csharp_style_namespace_declarations = file_scoped:warning csharp_style_prefer_primary_constructors = true:suggestion
dotnet_diagnostic.CA1852.severity = warning # 密封内部类型 csharp_style_namespace_declarations = file_scoped:warning csharp_style_prefer_primary_constructors = true:suggestion

Add dotnet_naming_rule entries for private field prefix (_camelCase) if detected

如果检测到私有字段前缀(_camelCase),添加dotnet_naming_rule条目

undefined
undefined

Anti-pattern Tracking

反模式跟踪

Use
detect_antipatterns
to track recurring quality issues across sessions.
Periodic Check:
→ detect_antipatterns (scope: solution)
  Track over time:
  - Are the same patterns recurring? (DateTime.Now keeps appearing)
  - Are new patterns emerging? (new HttpClient() in a new module)
  - Is the count trending up or down?
Prioritization:
| Anti-pattern | Count | Trend | Priority |
|-------------|-------|-------|----------|
| DateTime.Now | 12 | ↑ +3 | High — add to CLAUDE.md conventions |
| async void | 1 | → same | Medium — one-off fix |
| new HttpClient | 0 | ↓ -2 | Low — already fixing |
When patterns recur, add explicit rules to CLAUDE.md:
markdown
undefined
使用
detect_antipatterns
跟踪跨会话的重复质量问题。
定期检查:
→ detect_antipatterns(范围:解决方案)
  随时间跟踪:
  - 是否存在重复出现的模式?(DateTime.Now持续出现)
  - 是否出现新模式?(新模块中使用new HttpClient())
  - 数量趋势是上升还是下降?
优先级排序:
| 反模式 | 数量 | 趋势 | 优先级 |
|-------------|-------|-------|----------|
| DateTime.Now | 12 | ↑ +3 | 高 — 添加到CLAUDE.md规范中 |
| async void | 1 | → 持平 | 中 — 一次性修复 |
| new HttpClient | 0 | ↓ -2 | 低 — 已在修复 |
当模式重复出现时,在CLAUDE.md中添加显式规则:
markdown
undefined

Conventions

规范

  • NEVER use DateTime.Now — Use TimeProvider.GetUtcNow() (12 violations found, fixing)
undefined
  • 禁止使用DateTime.Now — 使用TimeProvider.GetUtcNow()(发现12处违规,正在修复)
undefined

Anti-patterns

反模式

Enforcing Without Detecting

未检测就强制执行

undefined
undefined

BAD — Imposing kit defaults on a project with its own conventions

错误示例 — 将工具包默认规则强加于有自身规范的项目

"All handlers should be internal sealed class"
"所有处理器都应为internal sealed class"

But this project uses public class with interfaces for testing

但该项目为测试使用public class和接口

undefined
undefined

GOOD — Detect first, then follow what exists

正确示例 — 先检测,再遵循现有规范

→ get_public_api reveals: 8/8 handlers are
public class
implementing
IHandler<T>
"This project uses public handlers with interfaces. Matching that convention."
undefined
→ get_public_api显示:8个处理器均为
public class
并实现
IHandler<T>
"该项目使用带接口的公开处理器。将匹配此规范。"
undefined

Overriding Explicit Project Rules

覆盖显式项目规则

undefined
undefined

BAD — Ignoring .editorconfig because kit says otherwise

错误示例 — 因工具包规则而忽略.editorconfig

.editorconfig says: csharp_style_expression_bodied_methods = false

.editorconfig设置:csharp_style_expression_bodied_methods = false

But generating expression-bodied methods anyway

但仍生成表达式体方法

undefined
undefined

GOOD — .editorconfig and Directory.Build.props always win

正确示例 — .editorconfig和Directory.Build.props始终优先

"Your .editorconfig disables expression-bodied methods. I'll use block-bodied methods to match your project settings."
undefined
"您的.editorconfig禁用了表达式体方法。 我将使用块体方法以匹配项目设置。"
undefined

Applying Generic Conventions to Unconventional Projects

对非常规项目应用通用规范

undefined
undefined

BAD — Forcing Clean Architecture naming on a VSA project

错误示例 — 将Clean Architecture命名强制应用于VSA项目

"You need a Services/ folder and a Repositories/ folder"
"您需要一个Services/文件夹和一个Repositories/文件夹"

But this project uses feature folders with everything co-located

但该项目使用功能文件夹,所有文件放在一起

undefined
undefined

GOOD — Match the project's organizational convention

正确示例 — 匹配项目的组织规范

"This project uses feature folders. I'll add the new feature at Features/Shipping/ with all related files together."
undefined
"该项目使用功能文件夹。我将在Features/Shipping/下添加新功能, 并将所有相关文件放在一起。"
undefined

Documenting Conventions Without Evidence

无依据记录规范

undefined
undefined

BAD — "Conventions" based on reading one file

错误示例 — 基于单个文件的“规范”

"Convention: Use var everywhere" (based on seeing var in one method)
undefined
"规范:所有地方都使用var"(基于在一个方法中看到var)
undefined

GOOD — Document only patterns confirmed across multiple files

正确示例 — 仅记录经多个文件验证的模式

→ get_public_api on 5 types: 100% use explicit types for non-obvious cases "Convention: Use explicit types for non-obvious cases (e.g., method returns), var for obvious cases (e.g., new MyClass()). Confirmed across 5 files."
undefined
→ 对5个类型执行get_public_api:100%对非明显场景使用显式类型 "规范:对非明显场景(如方法返回)使用显式类型, 对明显场景(如new MyClass())使用var。已在5个文件中验证。"
undefined

Decision Guide

决策指南

ScenarioActionTool
Joining existing projectRun full convention detection flowget_project_graph, get_public_api
Generating new codeCheck detected conventions firstPrevious detection results
Reviewing codeFlag convention deviationsget_public_api + comparison
Convention conflict (kit vs project)Project wins
Convention conflict (team disagreement)Document both, suggest .editorconfig
No conventions detectedUse kit defaults, document themarchitecture-advisor skill
Recurring anti-patternAdd to CLAUDE.md conventionsdetect_antipatterns
New team member onboardingRun detection, generate convention docFull detection flow
.editorconfig existsTrust it, don't overrideRead .editorconfig
No .editorconfigSuggest creating one based on detected patternsDetection + generation
Pattern seen onceCreate instinct at 0.3 confidence via
instinct-system
skill
instinct-system
Pattern confirmed 3+ timesInstinct auto-promotes to 0.7, suggest adding to CLAUDE.mdinstinct-system
场景操作工具
加入现有项目运行完整规范检测流程get_project_graph、get_public_api
生成新代码先检查检测到的规范之前的检测结果
审核代码标记规范偏差get_public_api + 对比
规范冲突(工具包vs项目)项目规则优先
规范冲突(团队意见分歧)记录两种情况,建议添加.editorconfig
未检测到规范使用工具包默认规则并记录architecture-advisor skill
重复出现的反模式添加到CLAUDE.md规范中detect_antipatterns
新团队成员入职运行检测,生成规范文档完整检测流程
存在.editorconfig信任该配置,不覆盖读取.editorconfig
无.editorconfig根据检测到的模式建议创建检测 + 生成
模式仅出现一次通过
instinct-system
skill创建置信度为0.3的直觉
instinct-system
模式被验证3次以上直觉自动提升至0.7,建议添加到CLAUDE.mdinstinct-system