Org Skills

salesforce-org-conventions

Apply the organisation's own Salesforce conventions — the naming rules and mandated patterns this org enforces on top of generic platform practice — across custom objects, fields, validation rules, page layouts, Lightning pages, Flows, custom labels, Apex classes, triggers and tests, and Visualforce.

Download .zip Raw Source
When agents use itUse this whenever the user creates or names any Salesforce metadata: a custom object or field, a junction object, a record type, a validation rule, a page or compact layout, a Lightning page, a Flow, a custom label, an Apex class, trigger, handler or test class, or a Visualforce page; writes a trigger that must sit on `TriggerTemplateV2`; needs a record type Id through `Utils.getRecordTypeId`; stores callout credentials in `Credential__c`; wires a bypass through `Ignore_Validation_Rules__c`; suffixes a class `Ctrl`, `Controller` or `Rest`; or simply asks "what should I call this". Also apply it when porting older metadata that predates these rules.

Install

Copilot (VS Code, Visual Studio, Copilot CLI and github.com) reads skills from the repository — commit them so the whole team gets them.

npx skills add AGCO-Global/org-skills --skill salesforce-org-conventions -a github-copilot
# or with the org installer (adds .github/skills/salesforce-org-conventions):
npx -y github:AGCO-Global/org-skills add skill salesforce-org-conventions

Uses the open skills CLI. Works with Claude Code, Codex, Cursor, Copilot, Gemini CLI, OpenCode, Windsurf and 60+ others — it asks which agent to install into.

npx skills add AGCO-Global/org-skills --skill salesforce-org-conventions
# user-level instead of project-level:
npx skills add AGCO-Global/org-skills --skill salesforce-org-conventions -g

Installs the salesforce-standards-skills plugin, which bundles all Salesforce / Standards skills and keeps them updated.

/plugin marketplace add AGCO-Global/org-skills
/plugin install salesforce-standards-skills@org-skills
# or just this skill, in this repository:
npx skills add AGCO-Global/org-skills --skill salesforce-org-conventions -a claude-code

Use Download .zip above, then upload it under Customize → Skills → Upload skill. Team and Enterprise admins can sync this repo as a plugin marketplace instead.

Installs into .agents/skills/, which Codex reads.

npx skills add AGCO-Global/org-skills --skill salesforce-org-conventions -a codex

Installs into Cursor's skills folder.

npx skills add AGCO-Global/org-skills --skill salesforce-org-conventions -a cursor

Installs into Gemini CLI's skills folder.

npx skills add AGCO-Global/org-skills --skill salesforce-org-conventions -a gemini-cli

Any tool with rules, instructions or custom prompts: use Copy SKILL.md above and paste it in. It is plain Markdown.

Commands use your normal git sign-in to GitHub, so they work while the repository is private. Node.js 20+ required.

Try it — example prompts

Prompts this skill is tested against, and what a good answer includes.

  • Write the trigger for our new Problem__c object.

    trigger ProblemTrigger on Problem__c with all 7 events declared (before/after insert, update, delete, plus after undelete) one line in the trigger body delegating through TriggerTemplateV2 a separate ProblemTriggerHandler class bypass wired per handler class in the trigger

  • I need a checkbox on Account for whether the customer is active, and a field for the date they signed up.

    checkbox labelled Active, API name Active__c — not Is_Active__c date field label and API name both ending in Date, e.g. Signed_Up_Date__c API names generated from the label rather than hand-written camel case FLS granted to System Administrator, System Specialist, System Specialist Lite and System Integration a Description filled in on each field

  • Create a junction object linking Problems and Parts. Problem controls sharing.

    object named Problem_Part__c with the primary parent Problem listed first singular object name no underscores in the object label two master-detail relationships, Problem first at least one record type on the object

  • How do I get the Digital Support record type Id for Case in this class?

    Utils.getRecordTypeId('Case:Digital_Support') stored in a static final variable constant named in ALL_CAPS_SNAKE_CASE

  • Name this flow — it runs on Problem before upsert for the Asset MQ Standard record type.

    Problem Asset_MQ Standard_Before_Upsert order is Object, Record Type Label, Context, Event a feature toggle so the flow can be switched off, as validation rules have

  • Where should the API key for our new ERP callout live?

    a Named Credential where the callout can use one otherwise Credential__c encrypted field and field-level security restricted to the integration user records kept out of change sets and packages

Skill contents

Salesforce Org Conventions

Targets: this organisation's Salesforce standards · Verified: 2026-09 against the team standards document

These are house rules, not platform rules. Where they differ from generic Salesforce advice they win, because reviewers enforce them and the existing codebase already follows them. Two habits carry most of the value: let the platform generate API names from well-chosen labels, and put every piece of logic behind the framework and helpers the org already owns rather than a new one. British English spelling throughout, in labels and API names alike.

1. Decide first

Question Default Change when
Trigger framework? TriggerTemplateV2, one trigger per object, all 7 events declared Never for new work — an object already on another framework is migrated, not forked
Where does a record type Id come from? Utils.getRecordTypeId('Case:Digital_Support') held in a static final Never a hard-coded Id and never an inline describe call
Where do callout credentials live? Credential__c or a Named Credential Named Credential whenever the callout can use one — see §3 for the Credential__c conditions
Do I need a new field? No — use a standard field, then an existing custom field Only when neither carries the meaning; then prefer a picklist over free text
API name? Whatever the platform generates from the label Never hand-written camel case; only the x prefix rule in §4 overrides this
Sharing declaration? with sharing without sharing with a comment saying why. Every class states one explicitly
Async work? The org's Async class, so context is handled for you Direct System.enqueueJob only where Async genuinely cannot express the job
Can this automation be switched off? Yes — validation rules and flows honour User.Ignore_Validation_Rules__c; each trigger handler has its own bypass Never ship automation with no way to disable it

2. Apex files, classes and members

  • Names. Classes start uppercase and UseCamelCase; variables and methods start lowercase and use camelCase; static final constants are ALL_CAPS_SNAKE_CASE. No non-ASCII characters in identifiers. Limit acronyms and abbreviations — a name should describe its purpose and still be readable and memorable.
  • Suffixes carry meaning. Visualforce and LWC controllers end in Ctrl or Controller (DemandPlanDemandPlanCtrl). Classes exposing REST endpoints end in Rest. Test classes are the class under test plus Test (AccountTriggerAccountTriggerTest).
  • Every file opens with the change log — date, name or initials, description of the change, and the user story or bug number. Template in references/apex-file-conventions.md.
  • DML goes through Database methods, so partial success is a decision rather than an accident; inspect the results you get back.
  • No SOQL or DML inside a loop, no hard-coded Ids, and no future or other async call from inside a loop.

3. Triggers and credentials

  • One trigger per object, named {ObjectName}Trigger, holding no logic — it hands off to {ObjectName}TriggerHandler through TriggerTemplateV2.
  • Declare all 7 eventsbefore insert, before update, before delete, after insert, after update, after delete, after undelete — even where a handler ignores some. Trigger Hook relies on the full set being present.
  • Bypass logic lives in the trigger, per handler class, so one handler can be switched off without disabling the object.
  • Never pass Trigger.new wholesale into a handler method. Filter to the records actually in scope for that piece of logic and pass those. It keeps the handler honest about what it operates on and keeps bulk behaviour predictable.
  • Callout credentials belong in Credential__c or a Named Credential, never in code, a static resource or a hard-coded string. A Credential__c record is ordinary data: store the secret in an encrypted field, restrict field-level security to the integration user, and keep the records out of change sets and packages.

Skeleton, bypass wiring and the Utils / Async call patterns: references/apex-file-conventions.md.

4. Objects and fields

  • Objects are singular, unique, start with an uppercase letter, and carry no underscores in the label. Junction objects are named for the two objects they join with the primary parent first — the one that drives sharing — as in Problem_Part__c.
  • Every object has at least one record type, and security comes from permission sets and profiles.
  • Field labels are short; detail belongs in help text and the description. Date fields end in Date; Date/Time labels end in Date/Time with the API name ending Date_Time; checkboxes are not prefixed Is; lookups name their target object; a label starting with a number gets an API name starting with x.
  • Add FLS to the four admin profiles — System Administrator, System Specialist, System Specialist Lite, System Integration — whenever a field is created. A field nobody in admin can see is a support ticket waiting to happen.
  • Turn on History Tracking only for fields that genuinely matter, and never paste picklist values from Word or Excel: they carry invisible characters that break comparisons later.

Full tables, including the spelling and acronym rules: references/object-and-field-naming.md.

5. Automation, layouts and Visualforce

  • Validation rules reference User.Ignore_Validation_Rules__c, hard-code no Ids, and place the error at the field rather than the top of the page.
  • Flows are named Object · Record Type Label (if any) · Context · Event, as in Problem Asset_MQ Standard_Before_Upsert, and carry a feature toggle the way validation rules do.
  • Approval processes hard-code no Ids, and field updates never use Re-evaluate Workflow Rules after Field Change.
  • Custom labels are not prefixed for common terms such as Save, and no two labels share a value.
  • Layouts never contain the word "Layout" in the name. Lightning pages are named {sobject API Name} Org Default, with the Details tab first, Related last, and anything object- or process-specific in between.
  • Visualforce links pages with {!$Page.PageName} rather than /apex/PageName, surfaces errors through <apex:pageMessages />, marks non-persisted data transient to shrink view state, and wraps dynamic SOQL input in String.escapeSingleQuotes().

Layout, list view, compact layout, lookup filter and Visualforce detail: references/layouts-and-ui.md.

6. Tests

Test classes are named after the class they cover and end in Test. Target 90 % or better coverage — the platform's 75 % is a deployment floor, not the bar here. Never SeeAllData=true. Split behaviour across multiple test methods, build shared data in @TestSetup, reset limits with Test.startTest() / Test.stopTest(), and cover the negative cases as well as the happy path. Test idioms and mocking belong to apex-testing.

7. Deliverable format

## What I created
<metadata type and API name, with the label it was generated from>

## Conventions applied
<the specific rules that shaped each name, so a reviewer can check them>

## Follow-ups
<FLS on the four admin profiles, record type, help text, bypass wiring — whatever is still outstanding>

Checklist

  • Every API name was generated from its label; none hand-written in camel case
  • Object names singular; junction objects named primary parent first
  • Date, Date/Time, checkbox, lookup and numeric-leading field rules applied
  • FLS granted to the four admin profiles; description and help text filled in
  • Trigger is one line on TriggerTemplateV2, declares all 7 events, bypasses per handler
  • No Trigger.new passed into a handler unfiltered
  • Record type Ids come from Utils.getRecordTypeId into a static final
  • Every class declares with sharing or without sharing, and opens with the change log
  • Validation rules and flows honour User.Ignore_Validation_Rules__c
  • Credentials in Credential__c (encrypted, FLS-restricted) or a Named Credential
  • Tests named {ClassUnderTest}Test, at 90 %+, with negative cases

Anti-patterns

  • Hand-written camel case API name (MyNewField__c from "My New Field") → let the platform generate it from the label
  • Plural object name, or underscores in the label → singular, spaces in the label
  • Checkbox called Is_Active__cActive__c; the type already says it is a boolean
  • Acronyms in a label or API name → spell it out; the abbreviation is obvious only to whoever coined it
  • Inline getRecordTypeInfosByDeveloperName() describe callUtils.getRecordTypeId(...) in a static final
  • Logic in the trigger body, or a second trigger on the object → one trigger, TriggerTemplateV2, handler holds the logic
  • Trigger.new handed straight to a handler method → filter to the records in scope and pass those
  • Picklist values pasted from Word or Excel → retype them; pasted values carry invisible characters
  • "Layout" in a layout name, or a Lightning page named ad hoc → drop the word; {sobject API Name} Org Default

Go deeper

  • references/object-and-field-naming.md — the complete object, field, picklist and FLS tables; open it when creating or renaming metadata
  • references/apex-file-conventions.md — change-log template, the TriggerTemplateV2 skeleton with all 7 events and bypass wiring, and the Utils, Async and Credential__c call patterns
  • references/layouts-and-ui.md — page, search, compact and list layouts, lookup filters, Lightning page structure, custom labels and the Visualforce rules
  • Sibling skills: apex-development for Apex idioms, apex-testing for tests, salesforce-data-model for modelling decisions, salesforce-automation for Flow design, salesforce-code-review for reviews

References

Deeper material the agent loads only when needed.