naming

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Naming

命名

One list, synced from the hub. The CI gate
naming
checks what a machine can check; the rest is your judgement. references/lint.md draws the line.
Before you name anything, run
node .agents/skills/naming/scripts/config.mjs
and read its output as the current rules: it prints references/naming.json merged with the project's overrides.
一份从中心同步的清单。CI 门禁
naming
检查机器能检查的部分;其余部分由你的判断决定。references/lint.md 划定了界限。
在命名任何东西之前,运行
node .agents/skills/naming/scripts/config.mjs
并阅读其输出,作为当前规则:它打印 references/naming.json 与项目覆盖合并后的结果。

Rules

规则

  1. One word per thing, and the word comes from
    CONTEXT.md
    . Look there first, then in existing types, DB tables and API routes. The repo's word beats the request's word.
    GoodBadWhy
    testimonial
    customerQuote
    the request said "customer quotes", the repo says
    testimonial
    Testimonial
    type,
    testimonials
    table,
    /api/testimonials
    Testimonial
    type,
    reviews
    table
    one word per thing, everywhere
    order
    purchase
    beside
    order
    two words for one thing splits the search
  2. No word yet? Run term-check, show the result to the user, get sign-off, then add the word to
    CONTEXT.md
    through domain-modeling, which owns that file.
    GoodBadWhy
    carryOver
    , term-checked, in
    CONTEXT.md
    carryOver
    , invented in the PR
    a new word needs the user's sign-off
    caseStudy
    recorded with plural
    caseStudies
    caseStudy
    with no entry
    the next agent picks a different word
    grid
    added to the role list
    Grid
    used, list unchanged
    a role outside the closed list is a new word
  3. Name by role, not by type. No
    I
    or
    T
    prefix, no Hungarian, no noise word (see
    noiseWords
    in naming.json).
    GoodBadWhy
    User
    IUser
    no
    I
    prefix
    count
    nCount
    no Hungarian
    accounts
    accountList
    ,
    accountData
    no noise word, the plural already says many
  4. Full words only, no single-letter name, no magic number. The banned short words are
    shortWords
    in naming.json.
    GoodBadWhy
    options
    opts
    full word
    error
    e
    ,
    err
    no single letter, no abbreviation
    const MAX_RETRIES = 3
    a bare
    3
    a number needs a name
  5. Say nothing the call site already says.
    GoodBadWhy
    user.name
    user.userName
    the object says
    user
    testimonials.add(item)
    testimonials.addTestimonial(item)
    the collection says
    testimonial
    field
    name
    in table
    testimonials
    field
    testimonial_name
    the table says
    testimonial
  6. An action starts with a verb from
    prefixes
    in naming.json, one verb per meaning. A pure derived value may be a noun.
    GoodBadWhy
    fetchTestimonials
    loadTestimonials
    beside it
    one verb per meaning,
    fetch
    is over the network
    listUsers
    getAllUsers
    list
    means many
    branchSha
    getBranchSha
    a pure derived value may be a noun
    A prefix promises its meaning:
    get
    only reads,
    set
    returns nothing,
    is
    returns a boolean,
    find
    may return nothing while
    get
    may not. A name with
    and
    in it (
    saveAndNotify
    ) is two functions.
  7. Stored boolean state is a bare adjective; a check is
    is
    ,
    has
    ,
    can
    or
    should
    ; never
    notX
    .
    GoodBadWhy
    archived
    isArchived
    stored state is a bare adjective
    isEmpty
    ,
    canRetry
    empty()
    ,
    retryAllowed
    a check carries the prefix
    enabled
    notDisabled
    positive names only
  8. Entity singular, collection plural. Record an irregular plural in
    CONTEXT.md
    next to the word.
    GoodBadWhy
    type
    Testimonial
    , file
    testimonial.ts
    type
    Testimonials
    one entity is singular
    table, path, folder
    testimonials
    table
    testimonial
    a collection is plural
    case_studies
    , plural recorded in
    CONTEXT.md
    case_studys
    an irregular plural is written down once
  9. No
    enum
    . Use a string-literal union or an
    as const
    object. The discriminant key is
    discriminant
    in naming.json (
    kind
    ). Own values are kebab-case; values mirrored from an external API stay verbatim.
    GoodBadWhy
    type Status = 'open' | 'in-progress'
    enum Status { Open }
    no
    enum
    { kind: 'pull-request' }
    { type: 'pull-request' }
    the discriminant key is
    kind
    'MERGED'
    from the GitHub API
    'merged'
    a mirrored value stays verbatim
  10. Build every name from
    parts
    in naming.json, big to small:
    project · area · entity · role · action · attribute · consumer
    . Take the parts you need, keep their order. Each
    artifacts
    entry lists parts, case and examples.
    role
    is a closed list per repo (
    artifacts.component.roles
    ,
    artifacts.env.roles
    ). Env vars follow
    artifacts.env.shape
    . Payload CMS: collection slug = API path = table; the slug is kebab-case and plural (
    case-studies
    ), the table replaces the hyphen with an underscore (
    case_studies
    ).
    GoodBadWhy
    COLIN_SYNC_KEY_FOR_TWENTY
    TWENTY_API_KEY
    issuer first, then what the key is for, then who holds it
    TestimonialGrid
    GridTestimonial
    entity first, then role
    testimonial.added
    addTestimonial
    an event is a fact in the past, not a command
  11. Casing follows the language guide and the repo's linter. Files and folders are lowercase kebab-case. An existing repo convention wins over this line: set it in
    artifacts.file.case
    and
    artifacts.folder.case
    , one case or a list (
    ["kebab", "PascalCase", "camelCase"]
    for React components and hooks).
    GoodBadWhy
    render-pr-body.mjs
    renderPrBody.mjs
    files are kebab-case
    src/components/case-studies/
    src/components/case_studies/
    folders are kebab-case
    loadUser
    in a repo that uses
    load
    everywhere
    fetchUser
    beside it
    the existing convention wins
  12. Meaning changed? Rename everywhere in the same change, rule 204 in writing-rules.
    GoodBadWhy
    draft
    renamed to
    proposal
    in code, docs and DB in one PR
    code renamed, docs still say
    draft
    two words for one thing
    retryCount
    after the value stopped being a limit
    maxRetries
    kept
    the name lies
    rename plus a
    CONTEXT.md
    update
    rename onlythe glossary is the source
  1. 每个事物一个词,且该词来自
    CONTEXT.md
    。先在那里查找,然后再在现有类型、数据库表和 API 路由中查找。仓库的用词优先于请求的用词。
    好坏原因
    testimonial
    customerQuote
    请求说“客户评价”,仓库说
    testimonial
    Testimonial
    类型、
    testimonials
    表、
    /api/testimonials
    Testimonial
    类型、
    reviews
    表
    每个事物一个词,处处如此
    order
    purchase
    与
    order
    并存
    一个事物两个词会分裂搜索
  2. 还没有词?运行 term-check,向用户展示结果,获得批准,然后通过 domain-modeling 将该词添加到
    CONTEXT.md
    ,该文件由它管理。
    好坏原因
    carryOver
    ,经过 term-check,在
    CONTEXT.md
    中
    carryOver
    ,在 PR 中发明
    新词需要用户批准
    caseStudy
    记录为复数
    caseStudies
    caseStudy
    无条目
    下一个 agent 会选择不同的词
    grid
    添加到角色列表
    使用
    Grid
    ,列表未改变
    封闭列表之外的角色是新词
  3. 按角色命名,而非按类型。不要
    I
    或
    T
    前缀,不要匈牙利命名法,不要噪音词(见 naming.json 中的
    noiseWords
    )。
    好坏原因
    User
    IUser
    无
    I
    前缀
    count
    nCount
    无匈牙利命名法
    accounts
    accountList
    ,
    accountData
    无噪音词,复数已经表示多个
  4. 只用完整单词,无单字母名称,无魔法数字。被禁止的短词是 naming.json 中的
    shortWords
    。
    好坏原因
    options
    opts
    完整单词
    error
    e
    ,
    err
    无单字母,无缩写
    const MAX_RETRIES = 3
    孤零零的
    3
    数字需要名字
  5. 不说调用点已经说过的内容。
    好坏原因
    user.name
    user.userName
    对象已经表明是
    user
    testimonials.add(item)
    testimonials.addTestimonial(item)
    集合已经表明是
    testimonial
    testimonials
    表中的字段
    name
    字段
    testimonial_name
    表已经表明是
    testimonial
  6. 动作以 naming.json 中
    prefixes
    里的动词开头,每个含义一个动词。纯粹派生值可以是名词。
    好坏原因
    fetchTestimonials
    loadTestimonials
    (旁边已有)
    每个含义一个动词,
    fetch
    表示通过网络
    listUsers
    getAllUsers
    list
    表示多个
    branchSha
    getBranchSha
    纯粹派生值可以是名词
    前缀承诺其含义:
    get
    只读取,
    set
    不返回任何内容,
    is
    返回布尔值,
    find
    可能不返回任何内容而
    get
    不能。名字中含
    and
    (如
    saveAndNotify
    )的是两个函数。
  7. 存储的布尔状态是裸形容词;检查用
    is
    、
    has
    、
    can
    或
    should
    ;绝不使用
    notX
    。
    好坏原因
    archived
    isArchived
    存储的状态是裸形容词
    isEmpty
    ,
    canRetry
    empty()
    ,
    retryAllowed
    检查带有前缀
    enabled
    notDisabled
    只用正面名称
  8. 实体单数,集合复数。在
    CONTEXT.md
    中记录不规则复数,紧跟该词。
    好坏原因
    类型
    Testimonial
    ,文件
    testimonial.ts
    类型
    Testimonials
    一个实体是单数
    表、路径、文件夹
    testimonials
    表
    testimonial
    集合是复数
    case_studies
    ,复数记录在
    CONTEXT.md
    中
    case_studys
    不规则复数只需写一次
  9. 不用
    enum
    。使用字符串字面量联合或
    as const
    对象。判别键是 naming.json 中的
    discriminant
    (
    kind
    )。自有值是 kebab-case;从外部 API 镜像的值保持原样。
    好坏原因
    type Status = 'open' | 'in-progress'
    enum Status { Open }
    不用
    enum
    { kind: 'pull-request' }
    { type: 'pull-request' }
    判别键是
    kind
    GitHub API 的
    'MERGED'
    'merged'
    镜像值保持原样
  10. 用 naming.json 中的
    parts
    构建每个名称,从大到小:
    project · area · entity · role · action · attribute · consumer
    。取你需要的部分,保持其顺序。每个
    artifacts
    条目列出部分、大小写和示例。
    role
    是每个仓库的封闭列表(
    artifacts.component.roles
    、
    artifacts.env.roles
    )。环境变量遵循
    artifacts.env.shape
    。Payload CMS:集合 slug = API 路径 = 表;slug 是 kebab-case 和复数(
    case-studies
    ),表将连字符替换为下划线(
    case_studies
    )。
    好坏原因
    COLIN_SYNC_KEY_FOR_TWENTY
    TWENTY_API_KEY
    先发行方,然后密钥用途,最后持有者
    TestimonialGrid
    GridTestimonial
    先实体,后角色
    testimonial.added
    addTestimonial
    事件是过去的实事,不是命令
  11. 大小写遵循语言指南和仓库的 linter。文件和文件夹是小写 kebab-case。现有仓库约定优先于此行:在
    artifacts.file.case
    和
    artifacts.folder.case
    中设置,一个大小写或列表(
    ["kebab", "PascalCase", "camelCase"]
    用于 React 组件和 hooks)。
    好坏原因
    render-pr-body.mjs
    renderPrBody.mjs
    文件是 kebab-case
    src/components/case-studies/
    src/components/case_studies/
    文件夹是 kebab-case
    在到处使用
    load
    的仓库中
    loadUser
    旁边用
    fetchUser
    现有约定优先
  12. 含义变了?在同一变更中处处重命名,writing-rules 中的规则 204。
    好坏原因
    draft
    在代码、文档和数据库中一个 PR 内重命名为
    proposal
    代码重命名,文档仍说
    draft
    一个事物两个词
    值不再是限制后改为
    retryCount
    保留
    maxRetries
    名字撒谎
    重命名并更新
    CONTEXT.md
    只重命名词汇表是源头

Per-project overrides

项目级覆盖

Override file:
.skilly/naming.json
, same shape as references/naming.json, only the keys you change. An old
docs/agents/naming.json
is read only while
.skilly/naming.json
is missing: move it to
.skilly/naming.json
.
  • Objects merge by key.
    null
    drops a key.
  • Arrays append and dedupe.
    "-Data"
    drops the default
    Data
    .
  • Scalars override.
json
{
  "prefixes": { "sync": { "meaning": "mirror to a remote system", "not": ["push", "mirror"] } },
  "noiseWords": ["-Data"],
  "allow": ["^ctx_"]
}
allow
holds one regex string per entry. What a match silences: references/lint.md.
覆盖文件:
.skilly/naming.json
,形状与 references/naming.json 相同,只包含你更改的键。旧的
docs/agents/naming.json
仅在缺少
.skilly/naming.json
时被读取:将其移动到
.skilly/naming.json
。
  • 对象按键合并。
    null
    删除键。
  • 数组追加并去重。
    "-Data"
    删除默认的
    Data
    。
  • 标量覆盖。
json
{
  "prefixes": { "sync": { "meaning": "镜像到远程系统", "not": ["push", "mirror"] } },
  "noiseWords": ["-Data"],
  "allow": ["^ctx_"]
}
allow
为每个条目保存一个正则字符串。匹配所静默的内容:references/lint.md。

References

参考

  • references/naming.json: prefixes, parts, artifacts, short words, noise words, synonyms, discriminant, allow
  • references/lint.md: what the CI gate checks, what you judge, per-repo exceptions
  • references/biome.json: opt-in Biome block for consumers
  • scripts/config.mjs: prints the merged config
  • references/naming.json:前缀、部分、构件、短词、噪音词、同义词、判别键、允许
  • references/lint.md:CI 门禁检查什么、你判断什么、每仓库例外
  • references/biome.json:供使用者选择加入的 Biome 块
  • scripts/config.mjs:打印合并后的配置