@salesforce/afv-skills 1.28.0 → 1.29.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/package.json +1 -1
  2. package/skills/dx-code-analyzer-configure/SKILL.md +31 -13
  3. package/skills/dx-code-analyzer-custom-rule-create/SKILL.md +484 -0
  4. package/skills/dx-code-analyzer-custom-rule-create/assets/pmd-ruleset-template.xml +31 -0
  5. package/skills/dx-code-analyzer-custom-rule-create/examples/metadata-xml-example-fields-api.md +87 -0
  6. package/skills/dx-code-analyzer-custom-rule-create/examples/metadata-xml-example-flows.md +105 -0
  7. package/skills/dx-code-analyzer-custom-rule-create/examples/metadata-xml-example-permissions.md +95 -0
  8. package/skills/dx-code-analyzer-custom-rule-create/examples/metadata-xml-examples.md +84 -0
  9. package/skills/dx-code-analyzer-custom-rule-create/examples/regex-examples.md +127 -0
  10. package/skills/dx-code-analyzer-custom-rule-create/examples/xpath-examples.md +227 -0
  11. package/skills/dx-code-analyzer-custom-rule-create/references/advanced-pmd-patterns.md +288 -0
  12. package/skills/dx-code-analyzer-custom-rule-create/references/apex-ast-reference.md +127 -0
  13. package/skills/dx-code-analyzer-custom-rule-create/references/eslint-custom-plugins.md +247 -0
  14. package/skills/dx-code-analyzer-custom-rule-create/references/eslint-rules-discovery.md +188 -0
  15. package/skills/dx-code-analyzer-custom-rule-create/references/eslint-tier2-configurable.md +114 -0
  16. package/skills/dx-code-analyzer-custom-rule-create/references/eslint-tier3-custom-plugins.md +113 -0
  17. package/skills/dx-code-analyzer-custom-rule-create/references/metadata-xml-rules.md +285 -0
  18. package/skills/dx-code-analyzer-custom-rule-create/references/regex-rule-schema.md +174 -0
  19. package/skills/dx-code-analyzer-custom-rule-create/references/troubleshooting.md +141 -0
  20. package/skills/dx-code-analyzer-custom-rule-create/references/xpath-patterns-governor-limits.md +83 -0
  21. package/skills/dx-code-analyzer-custom-rule-create/references/xpath-patterns-method-calls.md +108 -0
  22. package/skills/dx-code-analyzer-custom-rule-create/references/xpath-patterns-security.md +45 -0
  23. package/skills/dx-code-analyzer-custom-rule-create/references/xpath-patterns-structure.md +127 -0
  24. package/skills/dx-code-analyzer-custom-rule-create/references/xpath-patterns.md +131 -0
  25. package/skills/dx-code-analyzer-custom-rule-create/scripts/create-pmd-rule.js +209 -0
  26. package/skills/dx-code-analyzer-custom-rule-create/scripts/create-regex-rule.js +220 -0
  27. package/skills/dx-code-analyzer-run/SKILL.md +41 -8
  28. package/skills/mobile-platform-native-capabilities-integrate/SKILL.md +3 -3
  29. package/skills/platform-custom-field-generate/SKILL.md +86 -126
  30. package/skills/platform-custom-field-generate/references/advanced-picklists.md +590 -0
  31. package/skills/platform-value-set-generate/SKILL.md +305 -0
@@ -1,48 +1,33 @@
1
1
  ---
2
2
  name: platform-custom-field-generate
3
- description: "Use this skill when users need to create, generate, or validate Salesforce Custom Field metadata. Trigger when users mention custom fields, field types, Roll-up Summary fields, Master-Detail relationships, Lookup relationships, formula fields, picklists, or field metadata. Also use when users encounter field deployment errors, especially around Roll-up Summary format, Master-Detail constraints, or formula issues. Always use this skill for any custom field metadata work, field generation, or field troubleshooting."
3
+ description: "Use this skill when users need to create, generate, or validate Salesforce Custom Field metadata. Trigger when users mention custom fields, field types, Roll-up Summary fields, Master-Detail relationships, Lookup relationships, formula fields, picklists, dependent (controlling) picklists, referencing a value set from a field, or scoping/limiting picklist values for a specific record type. Also use when users encounter field deployment errors, especially around Roll-up Summary format, Master-Detail constraints, formula issues, or a record type that won't deploy without a business process. Use this skill for custom field metadata work, field generation, and field troubleshooting. DO NOT TRIGGER for creating or customizing the value set itself — defining a new GlobalValueSet, or modifying a StandardValueSet catalog like Industry or Lead Source — use platform-value-set-generate instead; this skill covers the field that references a value set, not the value set definition."
4
4
  metadata:
5
5
  version: "1.0"
6
+ minApiVersion: "51.0"
6
7
  ---
7
8
 
8
- ## When to Use This Skill
9
-
10
- Use this skill when you need to:
11
- - Create custom fields on any object
12
- - Generate field metadata for any field type
13
- - Set up relationship fields (Lookup or Master-Detail)
14
- - Create formula or roll-up summary fields
15
- - Troubleshoot deployment errors related to custom fields
16
-
17
9
  # Salesforce Custom Field Generator and Validator
18
10
 
19
11
  ## Overview
20
12
 
21
- Generate and validate Salesforce Custom Field metadata with mandatory constraints to prevent deployment errors. This skill has special focus on the **highest-failure-rate field types**: Roll-up Summary and Master-Detail relationships.
22
-
23
- ## Specification
24
-
25
- ## 1. Purpose
26
-
27
- This document defines the mandatory constraints for generating CustomField metadata XML. The agent must verify these constraints before outputting XML to prevent Metadata API deployment errors.
28
-
29
- **Critical Focus Areas:**
30
- - Roll-up Summary field format errors
31
- - Master-Detail field attribute restrictions
32
- - Lookup Filter restrictions
13
+ Generates and validates Salesforce CustomField metadata XML, with special handling for the **highest-failure-rate types** Roll-Up Summary and Master-Detail. The agent must verify the constraints below before outputting XML to prevent Metadata API deployment errors.
33
14
 
34
15
  ---
35
16
 
36
- ## 2. Universal Mandatory Attributes
17
+ ## 1. Universal Mandatory Attributes
37
18
 
38
19
  Every generated field must include these tags:
39
20
 
40
21
  | Attribute | Requirement | Notes |
41
22
  |-----------|-------------|-------|
42
- | `<fullName>` | Required | Derive from `<label>`: capitalize each word, replace spaces with `_`, append `__c`. Must start with a letter. E.g., label `Total Contract Value` → `Total_Contract_Value__c` |
23
+ | `<fullName>` | Required | **Field** name only: derive from `<label>` capitalize each word, replace spaces with `_`, append `__c`. Must start with a letter. E.g., label `Total Contract Value` → `Total_Contract_Value__c`. ⚠️ This rule is for the FIELD name. **Picklist VALUE `<fullName>` is different — keep it exactly as the user spelled it, spaces and all, no `__c`** (e.g. `Closed Won`, NOT `Closed_Won`). See [`references/advanced-picklists.md`](references/advanced-picklists.md) (ref §3). |
43
24
  | `<label>` | Required | The UI name (Title Case) |
44
- | `<description>` | Mandatory | State the business "why" behind the field |
45
- | `<inlineHelpText>` | Mandatory | Provide actionable guidance for the end-user. Must add value beyond the label (e.g., "Enter the value in USD including tax" instead of just "The amount") |
25
+ | `<description>` | Always include | Explain the business reason *why* this field exists. |
26
+ | `<inlineHelpText>` | Always include | Actionable end-user guidance that adds value beyond the label (e.g., "Enter the value in USD including tax", not "The amount"). |
27
+
28
+ `<description>` and `<inlineHelpText>` are mandatory outputs even though the Metadata API does not enforce them — omitting them produces low-quality metadata.
29
+
30
+ **File path (SFDX source format):** save each field as `force-app/main/default/objects/<Object>/fields/<FieldName>__c.field-meta.xml`, where `<Object>` is the object's API name (`Account`, `Opportunity`, or a custom `Inventory_Item__c`). A correct XML at the wrong path is never seen by the Metadata API.
46
31
 
47
32
  ### External ID Configuration
48
33
 
@@ -52,7 +37,7 @@ Every generated field must include these tags:
52
37
 
53
38
  ---
54
39
 
55
- ## 3. Technical Interplay: Precision, Scale, and Length
40
+ ## 2. Precision, Scale, and Length Rules
56
41
 
57
42
  To ensure deployment success, follow these mathematical constraints:
58
43
 
@@ -64,7 +49,7 @@ To ensure deployment success, follow these mathematical constraints:
64
49
 
65
50
  ### The "Fixed 255" Rule
66
51
 
67
- For standard TextArea types, the Metadata API requires `<length>255</length>`, even though it isn't configurable in the UI.
52
+ **TextArea: always include `<length>255</length>` exactly** — this literal value is required by the Metadata API and **omitting it fails deployment**, even though the UI exposes no length control. Unlike every other type where `length` is a value you calculate, TextArea's is a fixed constant.
68
53
 
69
54
  ### Visible Lines
70
55
 
@@ -72,9 +57,9 @@ Mandatory for Long/Rich text and Multi-select picklists to control UI height.
72
57
 
73
58
  ---
74
59
 
75
- ## 4. Field Data Types
60
+ ## 3. Field Data Types
76
61
 
77
- ### 4.1 Simple Attribute Types
62
+ ### 3.1 Simple Attribute Types
78
63
 
79
64
  | Type | `<type>` Value | Required Attributes |
80
65
  |------|----------------|---------------------|
@@ -89,7 +74,7 @@ Mandatory for Long/Rich text and Multi-select picklists to control UI height.
89
74
  | Currency | `Currency` | Default precision: 18, scale: 2 |
90
75
  | Percent | `Percent` | Default precision: 5, scale: 2 |
91
76
  | Phone | `Phone` | Standardizes phone number formatting |
92
- | Picklist | `Picklist` | `valueSet` with `valueSetDefinition` and `restricted` |
77
+ | Picklist | `Picklist` | `valueSet` containing EITHER `valueSetDefinition` (inline) OR `valueSetName` (reference); `restricted` (see "Picklist `restricted` default" below; advanced cases in §3.4) |
93
78
  | Text | `Text` | `length` (Max 255) |
94
79
  | Text Area | `TextArea` | `<length>255</length>` |
95
80
  | Text (Long) | `LongTextArea` | `length`, `visibleLines` (default 3) |
@@ -97,45 +82,73 @@ Mandatory for Long/Rich text and Multi-select picklists to control UI height.
97
82
  | Time | `Time` | Stores time only (no date) |
98
83
  | URL | `Url` | Validates for protocol and format |
99
84
 
100
- ### 4.2 Computed & Multi-Value Types
85
+ ### 3.2 Computed & Multi-Value Types
101
86
 
102
87
  | Type | `<type>` Value | Required Attributes |
103
88
  |------|----------------|---------------------|
104
89
  | Formula | Result type (e.g., `Number`) | `formula`, `formulaTreatBlanksAs` |
105
- | Roll-Up Summary | `Summary` | See Section 6 for complete requirements |
90
+ | Roll-Up Summary | `Summary` | See Section 5 for complete requirements |
106
91
  | Multi-Select Picklist | `MultiselectPicklist` | `valueSet`, `visibleLines` (default 4) |
107
92
 
108
- ### 4.3 Specialized Types
93
+ ### 3.3 Specialized Types
109
94
 
110
95
  | Type | `<type>` Value | Required Attributes |
111
96
  |------|----------------|---------------------|
112
97
  | Geolocation | `Location` | `scale`, `displayLocationInDecimal` |
113
98
 
114
- ### Picklist `restricted` Rule
115
-
116
- The `<restricted>` boolean inside `<valueSet>` controls whether only admin-defined values are allowed.
99
+ ### Picklist `restricted` default
117
100
 
118
- - IF user does not specify default to `<restricted>true</restricted>` (restricted, avoids performance issues with large picklist value sets)
119
- - IF user explicitly says the picklist should allow custom/new values, or mentions "unrestricted" or "open" → set `<restricted>false</restricted>`
120
- - Restricted picklists are limited to 1,000 total values (active + inactive)
101
+ **Always set `<restricted>true</restricted>`** inside `<valueSet>` unless the user explicitly says the picklist should accept custom values not in the admin-defined list (e.g. "unrestricted"/"open"). Restricted sets are capped at 1,000 total values (active + inactive). Minimal inline shape:
121
102
 
122
103
  ```xml
123
104
  <valueSet>
124
105
  <restricted>true</restricted>
125
106
  <valueSetDefinition>
126
107
  <sorted>false</sorted>
127
- <value>
128
- <fullName>Option_A</fullName>
129
- <default>false</default>
130
- <label>Option A</label>
131
- </value>
108
+ <value><fullName>Option_A</fullName><default>false</default><label>Option A</label></value>
132
109
  </valueSetDefinition>
133
110
  </valueSet>
134
111
  ```
135
112
 
113
+ ### 3.4 Advanced Picklists
114
+
115
+ The inline `<valueSetDefinition>` above is the simple case. Full rules and worked ✅/❌
116
+ examples for everything below are in
117
+ [`references/advanced-picklists.md`](references/advanced-picklists.md) — load it for any
118
+ non-trivial picklist. Section numbers in parentheses below (e.g. "ref §1") point to that
119
+ reference file, not to this skill. The hard rules:
120
+
121
+ - **Value-set reference (ref §1).** A `<valueSet>` holds EITHER `<valueSetName>` (reference) OR
122
+ `<valueSetDefinition>` (inline) — **never both**. Reference by the **bare** developer name —
123
+ Standard set `Industry`, GlobalValueSet `Priority_Levels` with **NO `__gvs`** and no `__c`
124
+ (the `__gvs` suffix is org-storage display only; the Metadata API uses the bare name). A
125
+ value-set-backed field is `<restricted>true</restricted>`. Creating the value set is the
126
+ `platform-value-set-generate` skill's job; this one only references it.
127
+ - **Value-name fidelity (ref §3).** A picklist value's `<fullName>`/`<label>` keep the user's exact
128
+ text **including spaces** (`Closed Won`, never `Closed_Won`). The space→`_` + `__c` rule is for
129
+ the FIELD name only.
130
+ - **Dependent picklists (ref §2).** Use the **modern API 38.0+** form: `<controllingField>` +
131
+ one `<valueSettings>` (`<controllingFieldValue>`+`<valueName>`) per pair; never the legacy
132
+ `<picklist>`/`<picklistValues>`/`<controllingFieldValues>` tags. **Both** controlling and
133
+ dependent fields MUST be `<restricted>true</restricted>`, even if the request doesn't say so.
134
+ - **Enhanced value attributes (ref §3).** `<value>` entries also accept `<color>` (hex, leading
135
+ `#`), `<isActive>` (`false` retires a value), and a value-level `<description>`.
136
+ - **Scoping a picklist to a record type (ref §5).** Per-record-type value visibility lives on the
137
+ **RecordType** (`<picklistValues>`), not the field. The RecordType file carries its own
138
+ `<fullName>` (bare developer name). **First decide if the object needs a BusinessProcess:**
139
+ only **Opportunity / Lead / Case / Solution** require one — they won't deploy without a
140
+ `<businessProcess>` (`Required field is missing: businessProcess`), even when only a custom
141
+ picklist is filtered. There you emit **two coupled files**: the `businessProcesses/<Name>.businessProcess-meta.xml`
142
+ file AND a matching `<businessProcess><Name></businessProcess>` inside the `<RecordType>` (after
143
+ `<active>`, before `<picklistValues>`; the `<fullName>` in the BP file is **bare**, never
144
+ object-qualified). **Custom objects (`*__c`) and all other standard objects (Account, Contact, …)
145
+ need NO BusinessProcess — emit the RecordType alone; do not invent one.** **Scope limit:**
146
+ picklist-value visibility per record type only — NOT general record-type authoring (compact
147
+ layouts, page layouts, branding).
148
+
136
149
  ---
137
150
 
138
- ## 5. Master-Detail Relationship Rules CRITICAL
151
+ ## 4. Master-Detail Relationship Rules CRITICAL
139
152
 
140
153
  Master-Detail fields have **strict attribute restrictions** that differ from Lookup fields. Violating these rules causes deployment failures.
141
154
 
@@ -165,28 +178,17 @@ Master-Detail fields have **strict attribute restrictions** that differ from Loo
165
178
  ```xml
166
179
  <CustomField xmlns="http://soap.sforce.com/2006/04/metadata">
167
180
  <fullName>Account__c</fullName>
168
- <label>Account</label>
169
181
  <type>MasterDetail</type>
170
182
  <referenceTo>Account</referenceTo>
171
183
  <relationshipName>Contacts</relationshipName>
172
184
  <relationshipOrder>0</relationshipOrder>
173
- <required>true</required> <!-- WRONG: Remove this -->
174
- <deleteConstraint>Cascade</deleteConstraint> <!-- WRONG: Remove this -->
175
- <lookupFilter> <!-- WRONG: Remove this entire block -->
176
- <active>true</active>
177
- <filterItems>
178
- <field>Account.Type</field>
179
- <operation>equals</operation>
180
- <value>Customer</value>
181
- </filterItems>
182
- </lookupFilter>
185
+ <required>true</required> <!-- WRONG: remove -->
186
+ <deleteConstraint>Cascade</deleteConstraint> <!-- WRONG: remove -->
187
+ <lookupFilter>...</lookupFilter> <!-- WRONG: remove entire block -->
183
188
  </CustomField>
184
189
  ```
185
190
 
186
- **Errors:**
187
- - `Master-Detail Relationship Fields Cannot be Optional or Required`
188
- - `Can not specify 'deleteConstraint' for a CustomField of type MasterDetail`
189
- - `Lookup filters are only supported on Lookup Relationship Fields`
191
+ **Errors:** `Master-Detail Relationship Fields Cannot be Optional or Required` · `Can not specify 'deleteConstraint' for a CustomField of type MasterDetail` · `Lookup filters are only supported on Lookup Relationship Fields`
190
192
 
191
193
  ### CORRECT — Master-Detail field:
192
194
 
@@ -240,7 +242,7 @@ Master-Detail fields have **strict attribute restrictions** that differ from Loo
240
242
 
241
243
  ---
242
244
 
243
- ## 6. Roll-Up Summary Field Rules CRITICAL
245
+ ## 5. Roll-Up Summary Field Rules CRITICAL
244
246
 
245
247
  Roll-up Summary fields have the **highest deployment failure rate**. Follow these rules exactly.
246
248
 
@@ -268,7 +270,7 @@ Roll-up Summary fields have the **highest deployment failure rate**. Follow thes
268
270
 
269
271
  **CRITICAL:** Both `summaryForeignKey` and `summarizedField` MUST use the fully qualified format:
270
272
 
271
- ```
273
+ ```text
272
274
  ChildObjectAPIName__c.FieldAPIName__c
273
275
  ```
274
276
 
@@ -311,51 +313,7 @@ ChildObjectAPIName__c.FieldAPIName__c
311
313
  </CustomField>
312
314
  ```
313
315
 
314
- ### CORRECT Roll-Up Summary (COUNT operation):
315
-
316
- ```xml
317
- <CustomField xmlns="http://soap.sforce.com/2006/04/metadata">
318
- <fullName>Line_Item_Count__c</fullName>
319
- <label>Line Item Count</label>
320
- <description>Count of related line items</description>
321
- <inlineHelpText>Automatically calculated from child records</inlineHelpText>
322
- <type>Summary</type>
323
- <summaryOperation>count</summaryOperation>
324
- <summaryForeignKey>Order_Line_Item__c.Order__c</summaryForeignKey>
325
- <!-- NO summarizedField needed for COUNT -->
326
- <!-- NO precision, scale, required, or length -->
327
- </CustomField>
328
- ```
329
-
330
- ### ✅ CORRECT — Roll-Up Summary (MIN operation):
331
-
332
- ```xml
333
- <CustomField xmlns="http://soap.sforce.com/2006/04/metadata">
334
- <fullName>Earliest_Due_Date__c</fullName>
335
- <label>Earliest Due Date</label>
336
- <description>Earliest due date among all line items</description>
337
- <inlineHelpText>Shows the soonest deadline</inlineHelpText>
338
- <type>Summary</type>
339
- <summaryOperation>min</summaryOperation>
340
- <summarizedField>Order_Line_Item__c.Due_Date__c</summarizedField>
341
- <summaryForeignKey>Order_Line_Item__c.Order__c</summaryForeignKey>
342
- </CustomField>
343
- ```
344
-
345
- ### ✅ CORRECT — Roll-Up Summary (MAX operation):
346
-
347
- ```xml
348
- <CustomField xmlns="http://soap.sforce.com/2006/04/metadata">
349
- <fullName>Highest_Price__c</fullName>
350
- <label>Highest Price</label>
351
- <description>Maximum unit price among all line items</description>
352
- <inlineHelpText>Shows the most expensive item</inlineHelpText>
353
- <type>Summary</type>
354
- <summaryOperation>max</summaryOperation>
355
- <summarizedField>Order_Line_Item__c.Unit_Price__c</summarizedField>
356
- <summaryForeignKey>Order_Line_Item__c.Order__c</summaryForeignKey>
357
- </CustomField>
358
- ```
316
+ **COUNT:** identical structure to SUM but **omit `<summarizedField>` entirely** (and keep `<summaryForeignKey>`). **MIN / MAX:** identical to SUM — just `<summaryOperation>min</summaryOperation>` or `max`, with `<summarizedField>` pointing at the field to find the minimum/maximum of. The Quick Reference table below covers all four.
359
317
 
360
318
  ### Roll-Up Summary Quick Reference
361
319
 
@@ -374,7 +332,7 @@ ChildObjectAPIName__c.FieldAPIName__c
374
332
 
375
333
  ---
376
334
 
377
- ## 7. Formula Field Rules
335
+ ## 6. Formula Field Rules
378
336
 
379
337
  ### Formula Result Types
380
338
 
@@ -419,26 +377,15 @@ A Formula is not a type itself. The `<formula>` tag is added to a field whose `<
419
377
  </CustomField>
420
378
  ```
421
379
 
422
- ### Formula Field Dependencies
423
-
424
- Formula fields that reference other fields will fail deployment if the referenced field does not exist or has not been deployed yet. Ensure all referenced fields are deployed before the formula field.
380
+ ### Formula Field Dependencies & Functions
425
381
 
426
- ### Specific Function Guidelines
427
-
428
- | Function | Rule |
429
- |----------|------|
430
- | `TEXT()` | MUST NOT be used with Text fields. If the field is already Text, remove the `TEXT()` wrapper. |
431
- | `CASE()` | Last parameter is always the default value. Total parameter count MUST be even (value-result pairs + default). |
432
- | `VALUE()` | MUST only be used with Text fields. If a Number is passed as parameter, remove the `VALUE()` wrapper. |
433
- | `DAY()` | MUST only be used with Date fields. If a DateTime field is used, convert it to Date first (e.g., `DAY(DATEVALUE(DateTimeField__c))`). |
434
- | `MONTH()` | MUST only be used with Date fields. If a DateTime field is used, convert it to Date first (e.g., `MONTH(DATEVALUE(DateTimeField__c))`). |
435
- | `DATEVALUE()` | MUST only be used with DateTime fields. If a Date field is used, remove the `DATEVALUE()` wrapper. |
436
- | `ISPICKVAL()` | MUST be used when checking equality of a Picklist field. NEVER use `==` with Picklist fields. |
437
- | `ISCHANGED()` | Use `ISCHANGED()` to check if a field value has changed. Do not manually compare with `PRIORVALUE()`. |
382
+ - Formula fields that reference other fields fail deployment if the referenced field doesn't exist or hasn't deployed yet — deploy referenced fields first.
383
+ - Use `ISPICKVAL()` (not `==`) for picklist comparisons.
384
+ - For the full formula-function reference (TEXT/VALUE/CASE/DAY/MONTH/DATEVALUE/ISCHANGED type rules), defer to the `platform-validation-rule-generate` skill, which owns formula-function correctness.
438
385
 
439
386
  ---
440
387
 
441
- ## 8. Common Deployment Errors
388
+ ## 7. Common Deployment Errors
442
389
 
443
390
  | Error Message | Cause | Fix |
444
391
  |---------------|-------|-----|
@@ -447,10 +394,14 @@ Formula fields that reference other fields will fail deployment if the reference
447
394
  | `DUPLICATE_DEVELOPER_NAME` | Field fullName already exists on the object | Use a unique business-driven name |
448
395
  | `MAX_RELATIONSHIPS_EXCEEDED` | More than 2 Master-Detail or 15 Lookup fields on the object | Use Lookup for 3rd+ Master-Detail; review Lookup count |
449
396
  | Reserved keyword error | Using `Order__c`, `Group__c`, etc. | Rename to `Status_Order__c`, etc. |
397
+ | `Value set must reference a value set name or define a value set, but not both` | `<valueSet>` has both `<valueSetName>` and `<valueSetDefinition>` | Keep exactly one (see Section 3.4) |
398
+ | `duplicate value found: [X] is defined multiple times` | Two `<value>` entries share a `<fullName>` | Make every picklist value `<fullName>` unique |
399
+ | `Invalid fullName` on a picklist value | Value `<fullName>` starts with a digit or contains hyphens | Start with a letter; no hyphens, no leading digit. Spaces ARE allowed — do NOT underscore them (see §3.4 value-name fidelity) |
400
+ | `Element ...picklist is not allowed` | Deprecated ≤37.0 dependent-picklist syntax (`<picklist>`/`<picklistValues>`/`<controllingFieldValues>`) | Use the modern `valueSettings`/`controllingFieldValue`/`valueName` form (Section 3.4) |
450
401
 
451
402
  ---
452
403
 
453
- ## 9. Verification Checklist
404
+ ## 8. Verification Checklist
454
405
 
455
406
  Before generating CustomField XML, verify:
456
407
 
@@ -471,6 +422,15 @@ Before generating CustomField XML, verify:
471
422
  - [ ] Is `<deleteConstraint>` set to `SetNull`, `Restrict`, or `Cascade`?
472
423
  - [ ] Is `<relationshipName>` in plural PascalCase?
473
424
 
425
+ ### Picklist Field Checks
426
+ - [ ] Does each `<valueSet>` contain EITHER `<valueSetName>` OR `<valueSetDefinition>` — never both?
427
+ - [ ] For a value-set reference: is `<restricted>true</restricted>` set?
428
+ - [ ] For a StandardValueSet reference: is the name the bare enum with NO `__c` (e.g. `Industry`)?
429
+ - [ ] For a GlobalValueSet reference: is the name the **bare** developer name with NO `__gvs` suffix?
430
+ - [ ] For dependent picklists: is `<controllingField>` set, with one `<valueSettings>` (`<controllingFieldValue>` + `<valueName>`) per pair?
431
+ - [ ] For dependent picklists: is the deprecated `<picklist>`/`<picklistValues>`/`<controllingFieldValues>` form ABSENT?
432
+ - [ ] Are all picklist value `<fullName>` values unique, start with a letter, and free of hyphens? (spaces are allowed — do NOT replace them with underscores, per the §3.4 value-name fidelity rule)
433
+
474
434
  ### Roll-Up Summary Field Checks CRITICAL
475
435
  - [ ] Is `<precision>` attribute ABSENT?
476
436
  - [ ] Is `<scale>` attribute ABSENT?