@salesforce/afv-skills 1.66.0 → 1.68.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 (165) hide show
  1. package/README.md +55 -5
  2. package/package.json +2 -4
  3. package/skills/agentforce-offline-experimentation-run/SKILL.md +26 -49
  4. package/skills/agentforce-offline-experimentation-run/scripts/bt_compare.py +81 -0
  5. package/skills/agentforce-offline-experimentation-run/scripts/bt_fetch.py +358 -0
  6. package/skills/agentforce-offline-experimentation-run/scripts/bt_patch_agent.py +110 -0
  7. package/skills/agentforce-offline-experimentation-run/scripts/btlib/__init__.py +34 -0
  8. package/skills/agentforce-offline-experimentation-run/scripts/btlib/agentpatch.py +483 -0
  9. package/skills/agentforce-offline-experimentation-run/scripts/btlib/agentsrc.py +565 -0
  10. package/skills/agentforce-offline-experimentation-run/scripts/btlib/cache.py +95 -0
  11. package/skills/agentforce-offline-experimentation-run/scripts/btlib/compare.py +617 -0
  12. package/skills/agentforce-offline-experimentation-run/scripts/btlib/fetch.py +1012 -0
  13. package/skills/agentforce-offline-experimentation-run/scripts/btlib/judge.py +148 -0
  14. package/skills/agentforce-offline-experimentation-run/scripts/btlib/messages.py +92 -0
  15. package/skills/agentforce-offline-experimentation-run/scripts/btlib/patch.py +327 -0
  16. package/skills/agentforce-offline-experimentation-run/scripts/btlib/redact.py +40 -0
  17. package/skills/agentforce-offline-experimentation-run/scripts/btlib/results.py +288 -0
  18. package/skills/agentforce-offline-experimentation-run/scripts/btlib/scoring.py +340 -0
  19. package/skills/agentforce-offline-experimentation-run/scripts/btlib/sfap.py +238 -0
  20. package/skills/agentforce-offline-experimentation-run/scripts/btlib/splits.py +136 -0
  21. package/skills/agentforce-offline-experimentation-run/scripts/btlib/stdm.py +98 -0
  22. package/skills/agentforce-offline-experimentation-run/scripts/btlib/tokens.py +173 -0
  23. package/skills/agentforce-offline-experimentation-run/scripts/btlib/units.py +199 -0
  24. package/skills/agentforce-offline-experimentation-run/scripts/btlib/versions.py +194 -0
  25. package/skills/agentforce-offline-experimentation-run/scripts/build_report.py +366 -378
  26. package/skills/agentforce-offline-experimentation-run/scripts/resolve-token.sh +14 -4
  27. package/skills/agentforce-offline-experimentation-run/scripts/sfap_replay.py +472 -796
  28. package/skills/commerce-react-storefront-create/SKILL.md +350 -0
  29. package/skills/consumer-goods-promotion-bo-api-deploy/SKILL.md +2 -2
  30. package/skills/consumer-goods-promotion-bo-api-deploy/references/generate-and-wire.md +28 -16
  31. package/skills/consumer-goods-promotion-bo-api-deploy/references/smoke-and-verify.md +18 -1
  32. package/skills/dx-lifecycle-center/SKILL.md +5 -2
  33. package/skills/dx-lifecycle-center/assets/widgets/connect-connected/connect-connected.json +65 -0
  34. package/skills/dx-lifecycle-center/assets/widgets/connect-connected/schema.json +32 -0
  35. package/skills/dx-lifecycle-center/assets/widgets/connect-sign-in/connect-sign-in.json +57 -0
  36. package/skills/dx-lifecycle-center/assets/widgets/connect-sign-in/schema.json +21 -0
  37. package/skills/dx-lifecycle-center/examples/workflows.md +20 -6
  38. package/skills/dx-lifecycle-center/references/connect-org.md +21 -2
  39. package/skills/dx-lifecycle-center/references/deploy.md +2 -2
  40. package/skills/dx-lifecycle-center/references/list-orgs.md +1 -1
  41. package/skills/dx-lifecycle-center/scripts/card-policy.jq +71 -0
  42. package/skills/dx-lifecycle-center/scripts/fill-widget.jq +29 -0
  43. package/skills/dx-lifecycle-center/scripts/widget.sh +28 -0
  44. package/skills/dx-org-devhub-configure/SKILL.md +85 -84
  45. package/skills/dx-org-devhub-configure/examples/status-output.md +25 -2
  46. package/skills/dx-org-devhub-configure/scripts/devhub.sh +265 -140
  47. package/skills/dx-org-devhub-configure/scripts/test-devhub.sh +100 -15
  48. package/skills/dx-packaging-move-to-2gp-migrate/SKILL.md +89 -0
  49. package/skills/dx-packaging-move-to-2gp-migrate/references/api-operations.md +164 -0
  50. package/skills/dx-scratch-def-configure/SKILL.md +163 -0
  51. package/skills/dx-scratch-def-configure/examples/confirm-card.md +53 -0
  52. package/skills/dx-scratch-def-configure/examples/report-recipes.md +100 -0
  53. package/skills/dx-scratch-def-configure/references/features.json +3270 -0
  54. package/skills/dx-scratch-def-configure/references/project-scratch-def.schema.json +1841 -0
  55. package/skills/dx-scratch-def-configure/references/settings-map.json +682 -0
  56. package/skills/dx-scratch-def-configure/scripts/lib_scratch_def.py +1306 -0
  57. package/skills/dx-scratch-def-configure/scripts/requirements.txt +3 -0
  58. package/skills/dx-scratch-def-configure/scripts/scrape_config_values.py +848 -0
  59. package/skills/education-cloud-domain-configure/SKILL.md +22 -24
  60. package/skills/education-cloud-domain-configure/references/dependent-features.md +9 -0
  61. package/skills/education-cloud-domain-configure/references/domain-features.md +15 -0
  62. package/skills/education-cloud-domain-configure/references/gotchas-extended.md +8 -0
  63. package/skills/education-cloud-domain-configure/references/setup-widgets.md +123 -0
  64. package/skills/education-cloud-multi-campus-configure/SKILL.md +1 -1
  65. package/skills/education-cloud-student-recruitment-agent-configure/SKILL.md +1 -1
  66. package/skills/experience-design-validate/SKILL.md +1 -1
  67. package/skills/experience-search-coordinate/SKILL.md +19 -13
  68. package/skills/experience-search-coordinate/references/content-route.md +79 -1
  69. package/skills/experience-search-coordinate/references/media-route.md +30 -4
  70. package/skills/experience-ui-bundle-features-generate/SKILL.md +1 -1
  71. package/skills/experience-ui-bundle-mfa-configure/SKILL.md +1 -1
  72. package/skills/field-service-data-capture-migrate/SKILL.md +1 -1
  73. package/skills/platform-apex-generate/SKILL.md +14 -11
  74. package/skills/platform-apex-test-generate/SKILL.md +2 -1
  75. package/skills/platform-datamask-run/SKILL.md +52 -71
  76. package/skills/platform-datamask-run/references/api-surface.md +10 -4
  77. package/skills/platform-datamask-run/references/policy-authoring.md +56 -7
  78. package/skills/platform-datamask-run/references/run-and-abort.md +17 -10
  79. package/skills/platform-datamask-run/scripts/poll-job.sh +15 -25
  80. package/skills/platform-dataspace-access-configure/SKILL.md +19 -1
  81. package/skills/platform-metadata-deploy/README.md +1 -1
  82. package/skills/platform-metadata-deploy/SKILL.md +114 -15
  83. package/skills/platform-metadata-deploy/references/agent-deployment-guide.md +3 -4
  84. package/skills/platform-metadata-deploy/references/orchestration.md +2 -3
  85. package/skills/platform-metadata-discovery-get/SKILL.md +185 -0
  86. package/skills/platform-metadata-discovery-get/references/api-map.md +25 -0
  87. package/skills/platform-metadata-discovery-get/references/h360-routes.md +30 -0
  88. package/skills/platform-metadata-discovery-get/references/scoped-soql.md +52 -0
  89. package/skills/platform-metadata-grounding-get/SKILL.md +170 -0
  90. package/skills/platform-policy-rule-generate/SKILL.md +84 -232
  91. package/skills/platform-policy-rule-generate/references/condition-model.md +47 -0
  92. package/skills/platform-policy-rule-generate/references/condition-templates.md +89 -0
  93. package/skills/platform-policy-rule-generate/references/conjunction-compiler.md +25 -0
  94. package/skills/platform-policy-rule-generate/references/conjunction-expression.md +22 -0
  95. package/skills/platform-policy-rule-generate/references/consumer-all.md +9 -0
  96. package/skills/platform-policy-rule-generate/references/consumer-datacloud-ui.md +91 -0
  97. package/skills/platform-policy-rule-generate/references/deploy-errors.md +24 -36
  98. package/skills/platform-policy-rule-generate/references/examples/ExistsJoinRLS/package.xml +12 -0
  99. package/skills/platform-policy-rule-generate/references/examples/ExistsJoinRLS/policyRuleDefinitionSets/ExistsJoinRLS.policyRuleDefinitionSet +6 -0
  100. package/skills/platform-policy-rule-generate/references/examples/ExistsJoinRLS/policyRuleDefinitions/ExistsJoinRLS_Rule_1.policyRuleDefinition +91 -0
  101. package/skills/platform-policy-rule-generate/references/examples/FieldReadDeny/package.xml +12 -0
  102. package/skills/platform-policy-rule-generate/references/examples/FieldReadDeny/policyRuleDefinitionSets/FieldReadDeny.policyRuleDefinitionSet +6 -0
  103. package/skills/platform-policy-rule-generate/references/examples/FieldReadDeny/policyRuleDefinitions/FieldReadDeny_Rule_1.policyRuleDefinition +72 -0
  104. package/skills/platform-policy-rule-generate/references/examples/LastCharactersFieldMasking/package.xml +12 -0
  105. package/skills/platform-policy-rule-generate/references/examples/LastCharactersFieldMasking/policyRuleDefinitionSets/LastCharactersFieldMasking.policyRuleDefinitionSet +6 -0
  106. package/skills/platform-policy-rule-generate/references/examples/LastCharactersFieldMasking/policyRuleDefinitions/LastCharactersFieldMasking_Rule_1.policyRuleDefinition +77 -0
  107. package/skills/platform-policy-rule-generate/references/examples/PrincipalFieldMatchRLS/package.xml +12 -0
  108. package/skills/platform-policy-rule-generate/references/examples/PrincipalFieldMatchRLS/policyRuleDefinitionSets/PrincipalFieldMatchRLS.policyRuleDefinitionSet +6 -0
  109. package/skills/platform-policy-rule-generate/references/examples/PrincipalFieldMatchRLS/policyRuleDefinitions/PrincipalFieldMatchRLS_Rule_1.policyRuleDefinition +77 -0
  110. package/skills/platform-policy-rule-generate/references/examples/TaggedObjectAccess/package.xml +12 -0
  111. package/skills/platform-policy-rule-generate/references/examples/TaggedObjectAccess/policyRuleDefinitionSets/TaggedObjectAccess.policyRuleDefinitionSet +4 -0
  112. package/skills/platform-policy-rule-generate/references/examples/TaggedObjectAccess/policyRuleDefinitions/TaggedObjectAccess_Rule_1.policyRuleDefinition +65 -0
  113. package/skills/platform-policy-rule-generate/references/headless-transport.md +87 -0
  114. package/skills/platform-policy-rule-generate/references/policy-schema-full.md +17 -10
  115. package/skills/platform-policy-rule-generate/references/policy-shapes.md +74 -0
  116. package/skills/platform-policy-rule-generate/references/principal-expression.md +31 -0
  117. package/skills/platform-policy-rule-generate/references/reference-resolution.md +51 -0
  118. package/skills/platform-policy-rule-generate/references/resource-expression.md +48 -0
  119. package/skills/platform-policy-rule-generate/references/runtime-context.md +9 -0
  120. package/skills/platform-policy-rule-generate/references/templates-access.md +11 -9
  121. package/skills/platform-policy-rule-generate/references/templates-advanced.md +4 -2
  122. package/skills/platform-policy-rule-generate/references/templates-record.md +37 -22
  123. package/skills/platform-policy-rule-generate/references/templates-transform.md +10 -8
  124. package/skills/platform-policy-rule-generate/references/templates.md +2 -2
  125. package/skills/platform-policy-rule-generate/references/ui-compatibility.md +35 -17
  126. package/skills/platform-report-generate/SKILL.md +9 -4
  127. package/skills/platform-report-generate/references/chart-types.md +26 -2
  128. package/skills/platform-report-generate/references/column-names.md +43 -0
  129. package/skills/platform-report-generate/references/errors-and-troubleshooting.md +1 -1
  130. package/skills/platform-report-generate/references/verification-checklist.md +10 -2
  131. package/skills/platform-value-set-generate/SKILL.md +19 -19
  132. package/skills/platform-widget-generate/SKILL.md +25 -51
  133. package/skills/platform-widget-generate/examples/formulas.json +19 -2
  134. package/skills/platform-widget-generate/examples/localized-labels.json +57 -0
  135. package/skills/platform-widget-generate/references/widget-actions.md +29 -0
  136. package/skills/platform-widget-generate/references/widget-bundle-validation.md +1 -0
  137. package/skills/platform-widget-generate/references/widget-formulas.md +24 -7
  138. package/skills/platform-widget-generate/references/widget-gotchas.md +10 -0
  139. package/skills/platform-widget-generate/references/widget-labels.md +78 -0
  140. package/skills/platform-widget-generate/references/widget-styling.md +12 -0
  141. package/skills/sales-call-scoring-configure/SKILL.md +17 -10
  142. package/skills/sales-call-scoring-configure/scripts/enable-call-scoring.sh +55 -33
  143. package/skills/service-digital-engagement-channel-configure/SKILL.md +11 -7
  144. package/skills/service-digital-engagement-channel-configure/assets/messaging_channel_template.xml +33 -0
  145. package/skills/service-digital-engagement-channel-configure/references/channel_settings.md +123 -16
  146. package/skills/service-digital-engagement-deployment-configure/SKILL.md +37 -100
  147. package/skills/service-digital-engagement-deployment-configure/assets/esd_web_update_template.xml +83 -8
  148. package/skills/service-digital-engagement-deployment-configure/examples/esd_web_prechat_fields.xml +74 -0
  149. package/skills/service-digital-engagement-deployment-configure/references/connect_api_creation.md +13 -3
  150. package/skills/service-digital-engagement-deployment-configure/references/deployment_settings.md +13 -78
  151. package/skills/service-digital-engagement-deployment-configure/references/onboarding_contract.md +5 -6
  152. package/skills/service-digital-engagement-deployment-configure/references/prechat_forms.md +245 -0
  153. package/skills/service-itsm-agentic-setup-incident-management/SKILL.md +164 -120
  154. package/skills/service-itsm-agentic-setup-incident-management/examples/output-templates.md +61 -37
  155. package/skills/service-itsm-agentic-setup-incident-management/references/audit-tracking.md +42 -0
  156. package/skills/service-itsm-agentic-setup-incident-management/references/broadcast-communications.md +23 -0
  157. package/skills/service-itsm-agentic-setup-incident-management/references/email-to-incident.md +23 -0
  158. package/skills/service-itsm-agentic-setup-incident-management/references/incident-dashboards.md +25 -0
  159. package/skills/service-itsm-agentic-setup-incident-management/references/incident-persona-psg.md +30 -146
  160. package/skills/service-itsm-agentic-setup-incident-management/references/incident-preferences.md +32 -136
  161. package/skills/service-itsm-agentic-setup-incident-management/references/major-incident-management.md +32 -155
  162. package/skills/service-itsm-agentic-setup-incident-management/references/manage-incidents-with-ai.md +45 -0
  163. package/skills/service-itsm-agentic-setup-incident-management/references/priority-matrix.md +32 -0
  164. package/skills/service-itsm-agentic-setup-incident-management/references/service-mgmt-privilege.md +30 -140
  165. package/skills/service-itsm-agentic-setup-incident-management/references/sla-milestones.md +110 -0
@@ -0,0 +1,170 @@
1
+ ---
2
+ name: platform-metadata-grounding-get
3
+ description: "Find metadata that already exists in a Salesforce org by meaning, when you do not know its exact API name. Use to find objects, fields, flows, Apex classes, picklist values, permission sets, validation rules, record types, and sharing rules by what they store or do. Use before creating metadata to check whether something similar already exists, and before writing Apex, LWC, SOQL, or Flow logic to confirm the real names. Use to read how a field, object, or validation rule is configured, and which profiles and permission sets can read or edit a field. Works through the Metadata Grounding MCP (search_metadata, query_metadata, describe_metadata) or the Salesforce MCP operations searchMetadata, queryMetadata, and describeMetadata. Needs Salesforce Catalog in the org. DO NOT TRIGGER for choosing between grounding, SOQL, and the CLI (use platform-metadata-discovery-get), retrieving source (platform-metadata-retrieve), or Data Cloud DLO and DMO schema (data360-code-extension-generate)."
4
+ metadata:
5
+ relatedSkills:
6
+ - data360-code-extension-generate
7
+ - platform-metadata-discovery-get
8
+ - platform-metadata-retrieve
9
+ version: "2.2"
10
+ accessCheck: "CDP.orgHasUnifiedCatalogProvisioned"
11
+ domains:
12
+ - "Platform"
13
+ mcpTools:
14
+ metadata-grounding:
15
+ tools:
16
+ - "search_metadata"
17
+ - "query_metadata"
18
+ - "describe_metadata"
19
+ semver: ">=1.0.0"
20
+ headless-360:
21
+ tools:
22
+ - "describe"
23
+ - "dispatch"
24
+ - "dispatch_readonly"
25
+ semver: ">=1.0.0"
26
+ cliTools:
27
+ - tool:
28
+ - "sf"
29
+ semver: ">=2.0.0"
30
+ id: "platform-metadata-grounding-get"
31
+ ---
32
+
33
+ # Salesforce Metadata Grounding
34
+
35
+ Metadata grounding searches the org's Salesforce Catalog, an index of the org's metadata with names, labels, descriptions, and configuration properties. It finds metadata by meaning, so "customer rewards status" can find a field labeled Loyalty Tier. It has three read-only operations: search, query, and describe.
36
+
37
+ Results are ranked and capped. They are never a complete list, and grounding never returns source.
38
+
39
+ ## When Not to Use Grounding
40
+
41
+ - Questions about standard Salesforce features or product behavior that do not depend on this org.
42
+ - A name you already know. Check it with scoped SOQL, which is exact and real time.
43
+ - A complete list, a count, or proof that something does not exist. Use scoped SOQL or `sf org list metadata`.
44
+ - Source to edit or deploy. Retrieve it with `platform-metadata-retrieve`.
45
+ - Where something is used, or what breaks if it changes. Grounding has no reference data.
46
+ - Metadata already returned in this conversation that has not changed since.
47
+
48
+ `platform-metadata-discovery-get` picks the right tool for each of these.
49
+
50
+ ## Pick the Server
51
+
52
+ Two servers reach the same catalog and return the same results. Use one server per request, never both for the same lookup.
53
+
54
+ The Salesforce MCP is shown in Setup today as the Headless360 (H360) MCP Server. On that server, `searchMetadata`, `queryMetadata`, and `describeMetadata` are operation ids that you pass to `describe` and `dispatch`. They are not tool names. The tools `search_metadata`, `query_metadata`, and `describe_metadata` exist only on the Metadata Grounding MCP.
55
+
56
+ | Order | Server | How to call |
57
+ |---|---|---|
58
+ | 1 | Metadata Grounding MCP | Call `search_metadata`, `query_metadata`, or `describe_metadata` with the inputs below. |
59
+ | 2 | Salesforce MCP, when the Metadata Grounding MCP is not connected or keeps failing | Call `describe` on the operation id `searchMetadata`, `queryMetadata`, or `describeMetadata`. Do not use `discover`, and do not describe the grounding recipe, which is too large to read. Then call the path `describe` returns with the same inputs. Use `dispatch_readonly` for `searchMetadata` and pass the inputs as query parameters. Use `dispatch` for `queryMetadata` and `describeMetadata`, which are POST calls but only read, and pass the inputs as the JSON body. Do not use other metadata search operations. |
60
+ | Neither connected | | Grounding is not available. Use the name and label fallback in `platform-metadata-discovery-get`. |
61
+
62
+ ## When a Call Fails
63
+
64
+ | What happens | What to do |
65
+ |---|---|
66
+ | The error says Salesforce Catalog is not enabled, or the user lacks the Customize Application permission | Stop using grounding on both servers for the rest of the session. Use the fallback and tell the user why, once. |
67
+ | Any other error or a timeout | Retry once. If it fails again, use the next server for this request. After failures on two requests, use the next server for the rest of the session. |
68
+ | The tool or server is not present | Start with the next server. |
69
+
70
+ A missing tool, an access error, or a 404 is not proof that the metadata does not exist.
71
+
72
+ ## Response Shapes
73
+
74
+ | Call | Metadata Grounding MCP | Salesforce MCP |
75
+ |---|---|---|
76
+ | Search | `{results, totalCount}` | Same payload in the response body |
77
+ | Describe and query | Wrapped as `{defaultExc: "<json string>", responseCode}`. Parse the `defaultExc` string to read `types`, `typeDetails`, or `records`. | Payload in the response body, not wrapped |
78
+ | Error | An array of `{errorCode, message}` | Same array in the response body |
79
+
80
+ Handle both shapes. If the response has a `defaultExc` string, parse it. Otherwise read the payload directly.
81
+
82
+ ## Catalog Type Names
83
+
84
+ Type names are case-sensitive, and some differ from Metadata API names.
85
+
86
+ | Metadata API name | Catalog type |
87
+ |---|---|
88
+ | CustomObject | `SObject` (subtypes `CustomObject`, `StandardData`) |
89
+ | CustomField | `SObjectField` (subtypes `CustomField`, `StandardField`, `CustomPersonAccountField`) |
90
+ | GlobalValueSet, StandardValueSet | `PicklistValueSet` (subtypes `Global`, `Standard`, `Local`) |
91
+ | FlexiPage | `Flexipage` |
92
+ | CustomTab | `Tab` |
93
+ | CustomApplication | `TabSet` |
94
+ | QuickAction | `QuickActionDefinition` |
95
+ | Queue | `Group` with subtype `Queue` |
96
+ | Role | `UserRole` |
97
+
98
+ Most other types use the Metadata API name, for example `ApexClass`, `ApexTrigger`, `Flow`, `PermissionSet`, `PermissionSetGroup`, `Profile`, `ValidationRule`, `RecordType`, `SharingRule`, `FieldPermissions`, `PicklistValue`, and `CustomPermission`.
99
+
100
+ Call describe with no `requests` only when a type you need is in neither list, and read only the type names. The full response is about 29K characters. Call describe with a `metadataType` only when you need that type's properties.
101
+
102
+ ## Search
103
+
104
+ Inputs:
105
+ - `query`: required plain-language phrase. An empty query returns `ILLEGAL_QUERY_PARAMETER_VALUE`.
106
+ - `metadataType`: optional catalog type name.
107
+ - `metadataSubType`: optional single value. It requires `metadataType`.
108
+ - `parentIdentifier`: optional, to search inside one object or permission container.
109
+ - `limit`: 1 to 100, default 50. Use 10 to 20.
110
+
111
+ How to search well:
112
+ 1. **Filter by type when you can.** For broad questions, run a few searches on likely types, such as `SObject`, `SObjectField`, and `Flow`, instead of one unfiltered search.
113
+ 2. **Search inside an object** by passing its returned identifier as `parentIdentifier`. First search `SObject` for the exact object API name, or reuse a field result's `parentIdentifier`, then copy the identifier unchanged. Never pass the raw object API name. This finds fields related to a topic. It is not a full field list.
114
+ 3. **Try one more phrasing** with synonyms or likely labels before you report "no match found in the org catalog."
115
+ 4. **Trust the service's exposure policy.** Do not infer visibility or support from API-name suffixes. Keep results relevant to the user's requested domain; intentionally exposed Data Cloud metadata must remain available when it is relevant.
116
+ 5. **Stop at search** when names, labels, and descriptions answer the question. Do not query after a search that returned nothing.
117
+
118
+ ## Query
119
+
120
+ Query returns full records with type-specific `properties`, such as a field's data type, required flag, length, formula, default, help text, and picklist value set.
121
+
122
+ Send exactly one of:
123
+ - `metadataIdentifiers`: 1 to 50 identifiers, to read the records themselves.
124
+ - `parentIdentifiers`: 1 to 10 identifiers, to read their child records.
125
+
126
+ Use `parentIdentifiers` for picklist values: search `PicklistValueSet` for the field, then pass the value set's identifier. Do not pass an object. That returns every field on it, which is very large (about 77KB for Contact). For a full field list, use scoped SOQL on `EntityParticle`.
127
+
128
+ Identifiers have three parts separated by `::`: the 18-character org id, the name, and the type. Use only identifiers the tools returned. Never build, shorten, or edit one.
129
+
130
+ ## Common Patterns
131
+
132
+ **Is there a field for this already?** Search `SObjectField` with the user's words and the object's `parentIdentifier`. Show the best matches with API name, label, and description.
133
+
134
+ **How is this field configured?** Search for the field, then query its identifier and read `properties`.
135
+
136
+ **What values does this picklist have?** Search `PicklistValueSet` for the field, then query the value set with `parentIdentifiers`.
137
+
138
+ **Who can read or edit this field?** Search `FieldPermissions` with the field's API name, such as `Contact.Loyalty_Tier__c`. Each result's parent is a profile or permission set. Query the results to read the read and edit flags. Results stop at 100, so for a complete list use scoped SOQL on `FieldPermissions`.
139
+
140
+ **What does this validation rule enforce?** Search `ValidationRule`, then query it for the formula, error message, and active flag.
141
+
142
+ ## Limits
143
+
144
+ - **Flows:** the header only, meaning process type, trigger type, trigger object, and active status. No elements or logic. Trigger object is not a filter, so searching cannot list every flow on an object.
145
+ - **Apex:** signatures only, no method bodies. Managed classes return an empty stub.
146
+ - **Pages and actions:** `Flexipage` and `QuickActionDefinition` records are not children of their object. Searching with the object as `parentIdentifier` does not find them. Search by meaning instead.
147
+ - **Not in the catalog:** page layouts, reports, custom metadata types, and custom settings.
148
+ - **Freshness:** the catalog can take several minutes to reflect deploys and other changes. For anything changed in this session, trust the deploy results and confirm with SOQL, which is real time.
149
+
150
+ ## Grounding Discipline
151
+
152
+ - Cite the API names, labels, and properties the tools returned. Say which statements are observed and which are inferred.
153
+ - Say "no match found in the org catalog." Never say the metadata does not exist.
154
+ - Never treat results as a complete list.
155
+ - Never write or deploy files built from query output. It returns properties, not source.
156
+ - Every identifier starts with the org id. If you also use the CLI or another tool, confirm both point to the same org before you combine results.
157
+
158
+ <!-- skill-validate: ignore-start -->
159
+ <!-- codey:operations start -->
160
+ ## Operations Reference
161
+
162
+ Operations this skill uses — routing and dependency reference.
163
+
164
+ | Operation | Purpose | Status | Call | Depends on |
165
+ |-----------|---------|--------|------|------------|
166
+ | `describe-metadata` | read | — | `POST /metadata-grounding/schema` | — |
167
+ | `search-metadata` | read | — | `GET /metadata-grounding/search` | — |
168
+ | `query-metadata` | read | — | `POST /metadata-grounding/query` | — |
169
+ <!-- codey:operations end -->
170
+ <!-- skill-validate: ignore-end -->
@@ -1,273 +1,125 @@
1
1
  ---
2
2
  name: platform-policy-rule-generate
3
- description: "Use this skill when authoring PolicyRuleDefinition and PolicyRuleDefinitionSet metadata XML for Salesforce Data Cloud governance policies, or when editing *.policyRuleDefinition / *.policyRuleDefinitionSet files. Covers the category decision tree, full schema for all policy variants (ACCESS, GOVERNANCE, RECORD, TRANSFORM), UI-compatibility rules for the Data Governance Policy Builder, output hygiene for user-facing agent responses, and validation guardrails. Do NOT use this skill for UserAccessPolicy, AccessPolicy, SharingRules, PermissionSet, or any other access-control metadata type — those have their own types and live outside the PolicyRuleDefinition schema."
3
+ description: "THE skill for creating a Data Cloud / Data Governance access policy — authors and deploys a PolicyRuleDefinitionSet + PolicyRuleDefinition pair (CRUD) covering OLS, FLS, RLS, masking/transform, and tag/classification-based access for the DATACLOUD or ALL consumer. TRIGGER when the user wants to create/write/author a Data Cloud or Data Governance policy, access policy, or policy rule, or to grant access to a Data Cloud object THROUGH A POLICY — a Data Cloud policy-create request routes here, not to the tag/classification surface. Resolves every reference via Data 360 MCP. SCOPE: Data Cloud policies only (not Security Center, DSAR, or User Access Policies). DO NOT TRIGGER to create tags/classifications, or to grant object/dataspace access via a PERMISSION SET / RBAC grant (use platform-dataspace-access-configure). For a vague object-access ask, surface both skills and ASK the permission-set way vs the policy way; if unsure the object is Data Cloud, ask which first."
4
4
  metadata:
5
- version: "1.0"
5
+ relatedSkills:
6
+ - "platform-dataspace-access-configure"
7
+ version: "2.0"
6
8
  domains: ["Platform", "Data 360"]
7
- minApiVersion: "64.0"
9
+ minApiVersion: "66.0"
8
10
  cliTools:
9
11
  - tool: ["jq"]
10
12
  semver: ">=1.6.0"
11
- - tool: ["sf"]
12
- semver: ">=2.0.0"
13
+ mcpTools:
14
+ data360:
15
+ tools: ["execute", "payload_examples", "search"]
16
+ semver: ">=1.0.0"
17
+ headless-360:
18
+ tools: ["discover", "describe", "dispatch", "dispatch_readonly"]
19
+ semver: ">=1.0.0"
13
20
  ---
14
21
 
15
- # Authoring Policy Rule Definitions
22
+ # Generate Policy Rule Metadata
16
23
 
17
- **Gating:** requires the `EnforceOMatic` and `PolicyRuleMDAPI` org permissions.
18
- **Min API version:** 64.0 (66.0 for conditions using `PolicyJsonExpression`).
24
+ This skill generates H360 policy metadata for the explicit `DATACLOUD` or `ALL` consumer. OLS, FLS, RLS, and Transform are shared policy shapes; `DATACLOUD` additionally requires the Data Governance Policy Builder contract. `ALL` uses the general metadata/runtime contract and does not inherit DG UI restrictions.
19
25
 
20
- This skill covers the **on-disk metadata XML format** for authoring policies. Use it whenever a task asks to write a `*.policyRuleDefinition` or `*.policyRuleDefinitionSet` file, or ship a metadata package containing them. The runtime side (RuleProvider, hooks) is out of scope.
26
+ ## When to use this skill (routing)
21
27
 
22
- ---
23
-
24
- > **Eval coverage:** This skill is exercised by the team's ADK eval framework, not by `tests/evals/` under the skill directory. Five datasets covering the ACCESS / GOVERNANCE / RECORD / TRANSFORM variants live in `packages/adk-eval/eval/domains/platform-policy-rule-generate/datasets/`.
25
-
26
- ## 1. Package Layout
27
-
28
- A deployable package always contains:
29
-
30
- ```text
31
- <fixture>/
32
- package.xml
33
- policyRuleDefinitionSets/<setName>.policyRuleDefinitionSet
34
- policyRuleDefinitions/<ruleName>.policyRuleDefinition
35
- ```
36
-
37
- `package.xml` template (use `<version>[ftest]</version>` for ftests, `64.0` or higher for real orgs):
38
-
39
- ```xml
40
- <?xml version="1.0" encoding="UTF-8"?>
41
- <Package xmlns="http://soap.sforce.com/2006/04/metadata">
42
- <types>
43
- <members>Rule0</members>
44
- <name>PolicyRuleDefinition</name>
45
- </types>
46
- <types>
47
- <members>Set1</members>
48
- <name>PolicyRuleDefinitionSet</name>
49
- </types>
50
- <version>64.0</version>
51
- </Package>
52
- ```
53
-
54
- ---
55
-
56
- ## 2. PolicyRuleDefinitionSet Schema
57
-
58
- ```xml
59
- <PolicyRuleDefinitionSet xmlns="http://soap.sforce.com/2006/04/metadata">
60
- <label>Set1</label>
61
- <description>Optional free text</description>
62
- <replicated>false</replicated> <!-- MinAppVersion 260 -->
63
- <builderCompatible>true</builderCompatible> <!-- MinAppVersion 262, author-settable -->
64
- <!-- builderValidated: server-managed — do not set in authored XML -->
65
- </PolicyRuleDefinitionSet>
66
- ```
67
-
68
- | Element | Req | Notes |
69
- |---------|-----|-------|
70
- | `<label>` | yes | Master label. File basename (devName) is the MDAPI identifier, not the label. |
71
- | `<description>` | no | Free text. |
72
- | `<replicated>` | no | `true` triggers placeholder transformation across companion orgs. Omit for null/false. |
73
- | `<builderCompatible>` | no | `true` = rules audited per §7 checklist. `false` = API-only. Omit = unaudited. Informational only — no deploy/runtime effect. |
74
- | `<builderValidated>` | no | **Server-managed. Never set in authored XML.** Server overwrites on validation. |
75
-
76
- ---
77
-
78
- ## 3. PolicyRuleDefinition — Core Fields
79
-
80
- | Element | Req | Notes |
81
- |---------|-----|-------|
82
- | `<label>` | yes | MasterLabel. |
83
- | `<category>` | yes | See §4. Drives `resourceScopeType` and whether `policyRuleResourceDomains`/`resourceTransform` are required. **Does NOT constrain `effect` outside of TRANSFORM.** |
84
- | `<effect>` | yes | `Permit`, `Forbid`, or `Transform`. The only category-coupling enforced by core: `effect=Transform ↔ category=TRANSFORM_POLICY_RULE_DEFINITION` (bidirectional). All other categories accept Permit and Forbid freely. |
85
- | `<action>` | yes (≥1) | `Read`, `TupleRead`, `Create`, etc. Multiple elements OR-combine. |
86
- | `<policyRuleDefinitionSetName>` | yes | Developer name of parent set. |
87
- | `<principalScopeType>` | yes | Always `ANY`. |
88
- | `<resourceScopeType>` | yes | `ANY`, `FIELD`, `RECORD`, `DATASPACE`, or `SPAN`. Must match category (§4). |
89
- | `<principalAuthenticationLevel>` | no | `INTERNAL`, `AUTHENTICATED`, `UNIDENTIFIED`, `IDENTIFIED`. |
90
- | `<ruleConsumer>` | no | `ALL`, `DATACLOUD`, `MULESOFT`, `TABLEAU`, `CORE`. |
91
- | `<policyRuleResourceDomains>` | no | Required for RECORD (RLS) and FIELD-scope TRANSFORM rules only. Forbidden on ACCESS/GOVERNANCE. |
92
- | `<resourceTransform>` | no | Required (and only valid) when `category=TRANSFORM`. |
93
- | `<whenPolicyRuleDefinitionClauseConjunction>` | no | WHEN conditions. |
94
- | `<unlessPolicyRuleDefinitionClauseConjunction>` | no | UNLESS conditions. Not UI-editable — prefer WHEN + negated operator. |
95
-
96
- ---
97
-
98
- ## 4. Category Decision Tree
28
+ This is the single entry point for **creating a Data Cloud / Data Governance access policy** (a `PolicyRuleDefinitionSet` + `PolicyRuleDefinition` pair). Any request to *create / write / author a policy, an access policy, a data governance policy, a Data Cloud policy, or a policy rule* (OLS / FLS / RLS / masking / tag- or classification-based object access) **whose target is Data Cloud** routes here — **do not** hand a Data Cloud policy-create request to the Data Governance tag/classification surface; that surface owns tags and classifications, not policy authoring.
99
29
 
100
- **Category names a domain (where in the platform's enforcement layers the rule applies). Effect names the action (allow / deny / transform). They are independent except for TRANSFORM.**
30
+ **Scope today: Data Cloud policies only.** This skill covers Data Cloud / Data Governance access policies. It does **not** yet cover core administrative policies, CMDB policies, or other non-Data-Cloud policy types (those are a planned future extension), and it is **not** the route for Security Center security policies, DSAR policies, or User Access Policies — leave those to their own core surfaces. If a policy-create request does not name Data Cloud and it is unclear whether the target object is a Data Cloud object, **ask which object first** (or whether it is Data Cloud) before routing here; core access-control surfaces (e.g. `scoped-access`) surfacing for a non-Data-Cloud request is legitimate.
101
31
 
102
- The **only** Category × Effect rule the platform validates:
32
+ Two adjacent skills, and how this one relates:
103
33
 
104
- - `effect=Transform` ⇔ `category=TRANSFORM_POLICY_RULE_DEFINITION` (bidirectional; mismatched throws `INVALIDFORCATEGORY`).
105
- - All other categories (`ACCESS`, `GOVERNANCE`, `RECORD`, `IDENTIFIED_RECORD`) accept either `Permit` or `Forbid`.
34
+ - **Data Governance tags / classifications** (create a tag, create/assign a classification, list governance tags): that is a *different* surface (`data360` Data Governance). This skill only *consumes* already-existing tags/classifications as policy references — it does not create them.
35
+ - **`platform-dataspace-access-configure`** — the **permission-set / RBAC** way to grant object or dataspace access (PermissionSet `dataspaceScopes` + the Object Access Grants Connect API). Data-space access grants go there.
106
36
 
107
- > **Note on the platform's auto-fill default:** When `<category>` is omitted from authored XML, the server fills it in from `effect`: `Permit→ACCESS`, `Forbid→GOVERNANCE`, `Transform→TRANSFORM`. **This is a default-fill, not a validation.** If you author an explicit category that contradicts this default, it is accepted and persisted as-is.
37
+ **Object access can be granted two ways — infer from context, ask only when vague.** For a Data Cloud / Data Governance object-access request, read the framing before acting:
108
38
 
109
- ### Picking the category
39
+ - The user is **driving from a permission set** (mentions a permission set, RBAC, or an object grant on a permset) → this is an **object access grant** → route to `platform-dataspace-access-configure`, no need to ask.
40
+ - The user **frames it as a policy** (says policy, access policy, policy rule, OLS/FLS/RLS, tag/classification-based) → **create the policy here**, no need to ask.
41
+ - The request is **genuinely vague** — "grant object access to X" with no mechanism and no clue → **ASK** whether they want the **permission-set way** (`platform-dataspace-access-configure`) or the **access-policy way** (this skill). If it is also unclear whether the object is Data Cloud, ask which object first.
110
42
 
111
- ```text
112
- What kind of policy?
113
- │
114
- ├── OLS/FLS allow/deny on tagged or classified resources
115
- │ category = ACCESS_POLICY_RULE_DEFINITION (allow/deny attestation in the access plane)
116
- │ | GOVERNANCE_POLICY_RULE_DEFINITION (governance-audited)
117
- │ effect = Permit | Forbid (chosen independently from category)
118
- │ resourceScopeType = ANY | FIELD | DATASPACE
119
- │ NO <policyRuleResourceDomains>
120
- │ condition: resourcePath=TAG|CLASSIFICATION CONTAINS_ANY <ref>
121
- │ For "objects AND all their fields" → action=TupleRead + OR-of-ENTITYTYPE clause (§7)
122
- │ Note: "Block access to Foo object" → tag Foo with <yourTag>, write rule on tag
123
- │ Do NOT use <resourceDomain>Foo</resourceDomain> — forbidden for ACCESS/GOVERNANCE
124
- │
125
- ├── Row-level filter on a DMO/DLO
126
- │ category = RECORD_POLICY_RULE_DEFINITION
127
- │ effect = Permit | Forbid
128
- │ resourceScopeType = RECORD
129
- │ <policyRuleResourceDomains> = the DMO/DLO API name ← entity targeting allowed here
130
- │
131
- ├── Identified-Guest record access
132
- │ NOT authorable via MDAPI — SESSION_CONSUMER_ID is not in RuleContextPathType
133
- │ Must be implemented as a runtime RuleProvider.
134
- │
135
- └── Field masking
136
- category = TRANSFORM_POLICY_RULE_DEFINITION ← required by RuleBuilder validator
137
- effect = Transform ← required by RuleBuilder validator
138
- resourceScopeType = FIELD (structured) or SPAN (unstructured)
139
- <policyRuleResourceDomains> = the DMO whose field is masked
140
- <resourceTransform> required (e.g. NULL_RESOURCE_TRANSFORM, LAST_N_CHARS_RESOURCE_TRANSFORM)
141
- ```
142
-
143
- ### ACCESS vs GOVERNANCE — how to choose
144
-
145
- Both legally accept Permit and Forbid. Pick by *which enforcement layer should record/audit the rule* and **what the prompt literally asks for**:
146
-
147
- | Use case | Pick | Reason |
148
- |---|---|---|
149
- | The prompt names "ACCESS policy rule" / "access rule" / "OLS/FLS" explicitly | `ACCESS_POLICY_RULE_DEFINITION` | Matches the prompt's vocabulary; sits in the data-access enforcement layer. |
150
- | The prompt names "governance" / "audit" / "policy framework" / data-residency or compliance language | `GOVERNANCE_POLICY_RULE_DEFINITION` | Matches the prompt's vocabulary; rules surface in governance reporting. |
151
- | Prompt is ambiguous and only describes allow/deny semantics | Default to `ACCESS` for Permit, `GOVERNANCE` for Forbid (mirrors the platform's auto-fill default; safe and deployable, but **not required**) |
152
-
153
- > **Important — honor the explicit category in the prompt.** If the prompt says "ACCESS policy rule that denies …" or "GOVERNANCE policy rule that permits …", emit exactly that category. Do not silently swap to the auto-fill default just because effect is Forbid (or Permit). The platform accepts both. The agent must not override the user's stated intent.
154
-
155
- **Scope × category compatibility** — any combination outside this matrix throws `INVALIDFORCATEGORY`:
156
-
157
- | | `ACCESS` | `GOVERNANCE` | `TRANSFORM` | `RECORD` |
158
- |------------|:--------:|:------------:|:-----------:|:--------:|
159
- | `ANY` | Yes | Yes | No | No |
160
- | `DATASPACE`| Yes | Yes | No | No |
161
- | `FIELD` | Yes | Yes | Yes | No |
162
- | `RECORD` | No | No | No | Yes |
163
- | `SPAN` | No | No | Yes | No |
164
-
165
- ---
166
-
167
- ## 5. Condition Patterns (Quick Reference)
168
-
169
- Every `<conditions>` block needs **all four**: `<clause>`, `<operator>`, one path element, and the value.
43
+ "Access to a **data space**" is the permission-set path — route it to `platform-dataspace-access-configure`.
170
44
 
171
- | Goal | path element | operator | value |
172
- |------|-------------|----------|-------|
173
- | Resource has tag | `<resourcePath>TAG</resourcePath>` | `CONTAINS_ANY` | `<valueReferenceType>CUSTOM_TAG` \| `STANDARD_TAG</valueReferenceType>` |
174
- | Resource has classification | `<resourcePath>CLASSIFICATION</resourcePath>` | `CONTAINS_ANY` | `CUSTOM_CLASSIFICATION` \| `STANDARD_CLASSIFICATION` |
175
- | Principal has permission | `<principalPath>ASSIGNED_PERMISSIONS_PATH</principalPath>` | `CONTAINS_ANY` \| `CONTAINS_NONE` | `<valueReferenceType>CUSTOM_PERMISSION</valueReferenceType>` |
176
- | Session in dataspace | `<contextPath>SESSION_DATASPACE</contextPath>` | `CONTAINS_ANY` | `<valueReferenceType>DATASPACE</valueReferenceType>` |
177
- | Record field = user attribute | `<resourcePath>RECORDFIELD</resourcePath>` + `<valueDomain>Schema:field</valueDomain>` | `EQUALS` | `<valuePrincipalPath>USER_ID` \| `ORGANIZATION_ID` \| `USER_ROLE_ID</valuePrincipalPath>` |
178
- | Entity type check | `<resourcePath>ENTITYTYPE</resourcePath>` | `IS` | `<valueString>{"t":"Text","v":"FIELD"}</valueString>` |
45
+ H360 policy **create / read / update** run over the headless-360 MCP `/headless/metadata` MD-CRUD path via `dispatch`: `discover`/`describe` the operation, then `dispatch` a POST create / PUT update of the generated XML and `dispatch_readonly` GET it back to verify. See `references/headless-transport.md` for the exact request/response shapes. There is **no `sf`/MDAPI fallback** — if the headless-360 MCP session is unavailable, or the type/op is not yet on the MD-CRUD allowlist (`400 UNSUPPORTED_OPERATION`), or the org lacks feature provisioning (`400 FIELD_INTEGRITY_EXCEPTION`), surface that gap to the operator rather than routing around it. This skill covers **create, read, update, and delete (CRUD)**. **Delete does NOT run over `/headless/metadata`** — Core has no real metadata delete (a metadata DELETE 405s, and the interim delete is a no-op 200 that removes nothing), so a policy is deleted over the Data 360 MCP **Data Governance Access Policy** surface (`d360_data_governance_access_policy_delete`), which removes the Access Policy and every embedded rule by developer name. See the "Deleting a Policy" section below. Use the Data 360 MCP tools to resolve exact org references before writing XML — `search`/`payload_examples`/`execute` against read-only lookup operations (tag, classification, dataspace, and every resource object: custom/derived DMO via `d360_dmo_list`/`d360_dmo_get`, standard DMO via `d360_data_model_objects_list`/`d360_data_model_object_get`, DLO via `d360_dlo_list`/`d360_dlo_get`, calculated insight object via `d360_ci_list`/`d360_ci_get`). Only when no Data 360 MCP session is reachable, resolve a custom `__dlm` DMO's fields by a read-only headless-360 `dispatch_readonly` sObject describe as a last resort (it can miss `__dlm` objects — see `references/reference-resolution.md`). Author **creates and updates only** over `/headless/metadata` MD-CRUD — never via a Data 360 MCP `_create`/`_update` operation; the Data 360 MCP mutation surface is used only for **delete** (`access_policy_delete`, whole-policy) and, to remove a single rule while keeping the policy, `access_policy_rule_replace`. All tag/classification/dataspace/DMO/DLO/CIO lookups stay read-only. Never resolve a reference through an `sf` CLI command.
179
46
 
180
- `<conjunctionExpression>` is 1-indexed prefix notation: `1`, `(AND 1 2)`, `(OR 1 2)`, `(AND (OR 1 2) (AND 3))`. A bare top-level index like `1` is valid for **deploy** but **crashes the Data Governance Policy Builder UI** — see §7 if UI editability matters.
47
+ ## Deterministic Workflow
181
48
 
182
- For full path enums (`RulePrincipalPathType`, `RuleResourcePathType`, `RuleContextPathType`), operators, and JSON expressions (PROJECTION / ARGLIST / SOQLTARGETLISTEXPR), see [`references/policy-schema-full.md`](references/policy-schema-full.md).
183
- For copy-paste templates for all policy variants, see [`references/templates.md`](references/templates.md).
49
+ 1. Require `consumer`: accept only `DATACLOUD` or `ALL`; do not infer or default it.
50
+ 2. Select the operating mode. Use normal author mode unless the request explicitly says to recreate a named retrieved evidence package exactly. In explicit evidence-recreation mode, the named API 69.0 example is authoritative: preserve its condition order, exact conjunctions, persisted `SCALAR_ATTRIBUTE`/`SOQLTARGETLISTEXPR` operands, and evidence values, while omitting `builderCompatible` and `builderValidated`. Exact recreation takes precedence over normal authoring rewrites and target-org re-resolution. It proves only evidence fidelity, not current-org authorability, runtime enforcement, or Policy Builder validation.
51
+ 3. Identify the policy set developer name and rule developer name.
52
+ 4. Choose the shared policy shape, category, effect, action, and resource scope **deterministically from the request signal** — do not ask the user "is this OLS/RLS/FLS?" when the signal is clear (read of a specific named object → RLS; hide a field → FLS; mask a field value → Transform; tag/classification tenant-wide → OLS). See `references/policy-shapes.md#selecting-the-shape-deterministic--do-not-ask-the-user`. Every renderable rule MUST carry **at least one resource condition** (principal conditions are optional; a zero-conditions or principal-only rule is not deployable/renderable) — if the shape has no valid resource condition (e.g. object-wide read with no row filter), obtain a resource condition or route object-wide read to the permission-set path (`platform-dataspace-access-configure`) rather than authoring an unrenderable rule.
53
+ 5. In normal author mode, resolve every tag, classification, custom permission, DMO/DLO, field, resource domain, join field, and principal field in the target org through MCP — never through an `sf` CLI command. Resolve tags, classifications, dataspaces, and every resource object's schema and fields through the Data 360 MCP read-only lookup operations from `references/reference-resolution.md#data-360-mcp-lookup-operations`. Resource objects are not only DMOs — resolve custom/derived DMOs (the `__dlm` suffix that most `resourceDomains` entries target) via `d360_dmo_list`/`d360_dmo_get` (family `DataModelObject`), standard/canonical DMOs via `d360_data_model_objects_list`/`d360_data_model_object_get` (family `DataModelObjectCatalog`), raw ingested DLOs via `d360_dlo_list`/`d360_dlo_get`, and calculated insight objects (CIOs) via `d360_ci_list`/`d360_ci_get`. `d360_dmo_get` returns the DMO with all field definitions; pass `includeFields:"true"` to `d360_dmo_list`. Only when no Data 360 MCP session is reachable, resolve a custom `__dlm` DMO's field API names with a read-only headless-360 `dispatch_readonly` sObject describe as a last resort — it can miss `__dlm` objects that are absent from the sObjects surface, so prefer `d360_dmo_get` whenever Data 360 MCP is available. For custom permissions and ID-valued principal comparisons (e.g. `ProfileId`), for which no Data 360 MCP lookup exists, resolve read-only through `dispatch_readonly` (a SOQL `/query` or metadata read). The MCP path addresses the org implicitly and `/headless/metadata` resolves the API version server-side, so no `ORG_ID`/`ORG_API_VERSION` resolution is needed; evidence-recreation fixtures retain the `{API_VERSION}` placeholder for the eval harness. User-provided values may be developer names, fully qualified names, labels, or partial descriptions: resolve each to the exact target-org developer/API name before generating XML. A Data 360 MCP lookup result's `id` is not the value to persist unless the field itself is ID-valued (e.g. `ProfileId`). For STANDARD_TAG/STANDARD_CLASSIFICATION `<valueReference>` values, construct the dotted path per `references/reference-resolution.md#constructing-valuereference-for-standard_tag--standard_classification` — it is not a single-field copy from the lookup record. For other `<valueDomain>`/`<select>` values, take the resolved developer/API name from the same record. When a label or description matches a reference, retain the resolved developer/API name in the metadata and do not emit the label unless the schema explicitly requires a label. Never invent reference names, infer a developer name from a label, or reuse evidence-package values.
54
+ 6. Construct the shared policy model from `references/condition-model.md`; reject `PLACEHOLDER` because it is internal-only.
55
+ 7. In normal author mode, if `consumer=DATACLOUD`, apply `references/consumer-datacloud-ui.md`: build a typed custom-conjunction plan for the API/UI projection, serialize it as nested MDAPI `conjunctionExpression` `AND`/`OR` groups, enforce one action and one resource domain, reject plural principal attributes, and validate directional scalar/RLS capabilities. If `consumer=ALL`, apply only `references/consumer-all.md` and base validation; make no UI-renderability claim. In evidence-recreation mode, preserve the named example's exact conjunction instead of recompiling it.
56
+ 8. Number conditions only after grouping is complete, validate complete conjunction coverage, then render XML. For evidence recreation, retain the evidence condition order and validate its existing numbering without rewriting it.
57
+ 9. Author the set XML and the definition XML as two components, omitting `builderCompatible` and `builderValidated`. The MD-CRUD path takes each component's XML directly as `xmlRep` (see step 10) — no `package.xml`/manifest or `ORG_API_VERSION` interpolation is required. Eval fixtures retain the `{API_VERSION}` placeholder for the harness.
58
+ 10. **Preview and confirm before writing.** The deterministic routing means no mid-flow clarifying questions; the single human checkpoint is here. Show the operator the resolved shape, target object/references, and the concrete rule (conditions + effect) and get an explicit go-ahead before the create/update dispatch. Then verify via the transport: flatten the generated `.policyRuleDefinitionSet`/`.policyRuleDefinition` XML to a single-line string (a defensive default — a properly-escaped multi-line `xmlRep` also persists, but single-line sidesteps any client that mangles newlines), `dispatch` a POST create (PUT for an update) to `/headless/metadata` for the set and then the rule, and `dispatch_readonly` GET each back to confirm a 2xx response. See `references/headless-transport.md` for the exact request/response shapes, the `xmlRep` newline guidance, and the transient-retry note. **UI-renderable-contract check:** the set read-back must carry server-added `<builderCompatible>false</builderCompatible>` and `<builderValidated>false</builderValidated>` even though neither was authored — `false` is EXPECTED for a hand-authored create ("not yet builder-validated," not "not renderable") and is the concrete signal the policy was accepted as a DG-builder-class object. Both flags remain server-managed; never author either one.
184
59
 
185
- ---
186
-
187
- ## 6. Validation Guardrails
188
-
189
- 1. Every `<conditions>` needs an `<operator>`. Missing operator → reject.
190
- 2. Every `<conditions>` needs at least one path element (`<resourcePath>`, `<principalPath>`, `<contextPath>`, or `<valueDomain>`).
191
- 3. `<contextPath>` is exclusively `SESSION_DATASPACE`. Never put a resource path value there.
192
- 4. Scope × category must be in the §4 matrix. Common offenders: ACCESS/GOVERNANCE + RECORD scope; RECORD + ANY/FIELD scope; TRANSFORM + ANY/RECORD scope. (Effect is independent of category except for TRANSFORM — see §4.)
193
- 5. `<resourceTransform>` and `effect=Transform` are coupled. Transform effect needs a resourceTransform. Permit/Forbid must not have one.
194
- 6. `<policyRuleResourceDomains>` is **required** for RECORD (RLS) and FIELD-scope TRANSFORM; **forbidden** on ACCESS/GOVERNANCE.
195
- 7. `<conjunctionExpression>` indices must match actual `<conditions>` count. Off-by-one → reject.
196
- 8. `<clause>` inside `<conditions>` must match the wrapper (`WHEN` inside `<when…>`, `UNLESS` inside `<unless…>`).
197
- 9. JSON literals in `<valueString>` must escape `"` to `&quot;`. Wrong escaping silently corrupts the literal.
198
- 10. Reference targets (`<valueReference>`, `<resourceDomain>`) must exist in the target org at deploy time.
199
- 11. `SCALAR_ATTRIBUTE` / `PLURAL_ATTRIBUTE` are not in `RulePrincipalPathType` — not in MDAPI contract. Use a runtime RuleProvider for those shapes.
200
- 12. `IDENTIFIED_RECORD` is not authorable via MDAPI — `SESSION_CONSUMER_ID` not in `RuleContextPathType`.
201
- 13. Standard tag/classification dev names are fully-qualified dotted paths (e.g. `DataGovernanceTags.ExternalData.Visibility.Public`). Retrieve an existing rule to get the exact string before authoring.
202
- 14. Min API versions: `PolicyRuleDefinition` = 64.0; `PolicyJsonExpression` conditions = 66.0; `<replicated>` = 260+; `<builderCompatible>` / `<builderValidated>` = 262+.
203
-
204
- > **Note on `<conjunctionExpression>` shape:** A bare top-level index (e.g. `<conjunctionExpression>1</conjunctionExpression>`) deploys cleanly — the server-side parser accepts bare tokens at the top level. It is **not** a deploy-time validation error. It does, however, crash the Data Governance Policy Builder UI on load — see §7.
205
-
206
- ---
60
+ ## Deleting a Policy
207
61
 
208
- ## 7. UI Compatibility — Core Rules
62
+ Delete a policy over the Data 360 MCP **Data Governance Access Policy** surface, **not** `/headless/metadata` — Core has no real metadata delete (a metadata DELETE 405s or no-ops), so it never belongs on that transport. A `PolicyRuleDefinitionSet` authored by this skill surfaces there as an **Access Policy** addressable by its developer name. Because hand-authored sets land `builderCompatible: false`, an `access_policy_list` needs `includeIncompatible: true` to show them, but `access_policy_get` and `access_policy_delete` work by name regardless of builder-compatibility.
209
63
 
210
- The Data Governance Policy Builder edits a **strict subset** of the MDAPI. Default goal: produce UI-compatible policies. Always confirm with the operator before producing API-only XML.
64
+ `d360_data_governance_access_policy_delete` takes a single `name` (the set's developer name) and is a **whole-policy delete**: one call removes the Access Policy **and every embedded rule** (its `PolicyRuleDefinition` members). There is therefore **no leaf-before-parent ordering** and **no discrete single-rule delete** — to drop one rule while keeping the policy, re-author the surviving rule set via `d360_data_governance_access_policy_rule_replace` instead. Confirm the delete by reading the policy back with `d360_data_governance_access_policy_get` by name: a not-found result (or the policy being absent from an `includeIncompatible` list) is the success signal. There is **no `sf` CLI fallback**.
211
65
 
212
- **Hard blockers** — any of these make the policy uneditable (and several crash the builder on load):
66
+ ## Validated Policy Shapes
213
67
 
214
- - **Missing OR-of-ENTITYTYPE clause on ACCESS/GOVERNANCE rules** → hard crash: `Cannot use 'in' operator to search for 'Permit' in undefined`. Required even when paired with `TupleRead` (where it's functionally redundant at runtime). Must include `IS` conditions for `{"t":"Text","v":"OBJECT"}` and `{"t":"Text","v":"FIELD"}`.
215
- - **Bare top-level condition index** in `<conjunctionExpression>` (e.g. `1`, or `(AND (OR 1 2) 3)`) → crash on builder load in `buildCriteria`. Deploy is unaffected, but the policy is uneditable in the UI. Always wrap: `(AND 1)` for a single condition; `(AND (OR 1 2) (AND 3))` instead of `(AND (OR 1 2) 3)`.
216
- - `category = ACCESS_POLICY_RULE_DEFINITION` + `effect = Forbid` → the **Data Governance Policy Builder UI** (not MDAPI) collapses it to GOVERNANCE on save; round-trip via the builder will rewrite the category. MDAPI deploy is unaffected — the original ACCESS+Forbid combination is valid and deploys without modification. If your goal is UI round-trippability, prefer GOVERNANCE for Forbid; if the source of truth is MDAPI, ACCESS+Forbid is fine.
217
- - Any `<unlessPolicyRuleDefinitionClauseConjunction>` block → silently dropped on first UI save.
218
- - More than one `<action>` → only the first is kept.
219
- - `ruleConsumer` ≠ `DATACLOUD` → UI hardcodes DATACLOUD on save.
220
- - Top-level `(OR 1 2)` conjunction → triggers `// ERROR: Unsupported rule!` path, rule silently dropped.
68
+ For an object-level security policy with tags/classifications and principal conditions, begin with `references/examples/TaggedObjectAccess/`. Select the conjunction contract from the explicit consumer: `DATACLOUD` requires the UI custom-conjunction form; `ALL` uses the general form.
221
69
 
222
- **UI-compatible "unless" rewrite:**
70
+ The real example has:
223
71
 
224
- | Author intent | UI-compatible shape |
225
- |---|---|
226
- | `unless principal has permission X` | `WHEN ASSIGNED_PERMISSIONS_PATH CONTAINS_NONE X` |
227
- | `unless resource has tag X` | `WHEN TAG CONTAINS_NONE X` |
228
- | `unless record field = value` | `WHEN RECORDFIELD NOT_EQUALS value` |
72
+ - One `PolicyRuleDefinitionSet`: `TaggedObjectAccess`.
73
+ - One `PolicyRuleDefinition`: `TaggedObjectAccess_Rule_1`.
74
+ - `GOVERNANCE_POLICY_RULE_DEFINITION`.
75
+ - `Permit` and `TupleRead`.
76
+ - `ANY` resource scope.
77
+ - Two entity-type conditions, one principal-permission condition, one principal-expression condition, and two tag conditions.
78
+ - A grouped conjunction expression: `(AND (OR 1 2) (AND 3 4) (AND 5 6))`.
229
79
 
230
- For the full UI-compatibility checklist, round-trip rules, and operator support matrix, see [`references/ui-compatibility.md`](references/ui-compatibility.md).
80
+ For the validated field-level security deny shape, use `references/examples/FieldReadDeny/`: `GOVERNANCE_POLICY_RULE_DEFINITION`, `Forbid`, `Read`, and one entity-type discriminator whose right operand is `FIELD`. This example validates the deny shape; it does not establish that every other FLS shape is invalid.
231
81
 
232
- ---
82
+ For the validated field-masking shape, use `references/examples/LastCharactersFieldMasking/`: `TRANSFORM_POLICY_RULE_DEFINITION`, `Transform`, `Read`, `FIELD` scope, an explicit `resourceTransform`, and one entity-type discriminator whose right operand is `FIELD`. The retrieved `LAST_N_CHARS_RESOURCE_TRANSFORM` uses a top-level `resourceExpression` of type `ARGLIST`; do not generalize its argument shape to other transforms.
233
83
 
234
- ## 8. Authoring Workflow
84
+ For the validated row-level security shapes, use `references/examples/PrincipalFieldMatchRLS/` for direct record-field comparisons and `references/examples/ExistsJoinRLS/` for an `EXISTS` join block. Both use `RECORD_POLICY_RULE_DEFINITION`, `Permit`, `Read`, `RECORD` scope, and an exact target DMO in `policyRuleResourceDomains`. Resolve every DMO and field in the target org before authoring.
235
85
 
236
- 1. **Start from the closest template** in [`references/templates.md`](references/templates.md) — modify from there, don't start blank.
237
- 2. **Pick category first** (§4). Category fixes effect, resourceScopeType, and whether policyRuleResourceDomains/resourceTransform are required.
238
- 3. **Lay out the bare rule**: top-level fields only, no conditions. Match the category template in [`references/templates.md`](references/templates.md).
239
- 4. **Add conditions one at a time**, each with all four anchors: `<clause>`, `<operator>`, one path element, and the value.
240
- 5. **Update `<conjunctionExpression>`** — 1-indexed prefix notation. Bare top-level index (e.g. `1`) deploys but breaks the UI; wrap as `(AND 1)` if UI editability matters (§7).
241
- 6. **Run the UI-compatibility check** (§7 / [`references/ui-compatibility.md`](references/ui-compatibility.md)). If any item trips, attempt the "unless" rewrite first; if not possible, get explicit operator confirmation before continuing.
242
- 7. **Update `package.xml`** — list each `<members>` for both types.
243
- 8. **Set `<builderCompatible>`** on the set to `true` if §7 checklist passes; `false` if intentionally API-only.
244
- 9. **Sanity-check against §6 (guardrails)** before considering done.
245
- 10. **Validate with dry-run** before any non-dry deploy to a persistent org. Surface errors using the error reference in [`references/deploy-errors.md`](references/deploy-errors.md).
86
+ Dataspace-scoped OLS is parked and unsupported because the UI-retrieved references did not pass MDAPI validation in the source org. Do not construct it until a separately validated real-org shape is available.
246
87
 
247
- **Three-layer correctness check** before done:
248
- - **Runtime enforcement** — does the rule enforce what's intended? (action choice, condition shape)
249
- - **MDAPI deploy validity** — does it deploy? (§6 guardrails, scope×category, tag dev names, org perms)
250
- - **UI editability** — can the builder render and re-save it? (§7 checklist, OR-of-ENTITYTYPE requirement)
88
+ ## Required References
251
89
 
252
- ---
90
+ - `references/condition-model.md`: how to construct a condition as left operand, operator, and right operand.
91
+ - `references/condition-templates.md`: copyable condition shapes.
92
+ - `references/resource-expression.md`: resource-side projections, joins, aliases, and predicates.
93
+ - `references/policy-shapes.md`: deterministic OLS, FLS, and masking top-level fields.
94
+ - `references/principal-expression.md`: principal-side `SOQLTARGETLISTEXPR` expressions.
95
+ - `references/conjunction-expression.md`: one-indexed boolean grouping.
96
+ - `references/reference-resolution.md`: exact target-org reference resolution.
97
+ - `references/headless-transport.md`: the `dispatch`/`dispatch_readonly` `/headless/metadata` request/response shapes (the sole transport; no CLI fallback).
98
+ - `references/consumer-datacloud-ui.md`: Data Governance UI grouping, cardinality, scalar attributes, and RLS field capabilities.
99
+ - `references/consumer-all.md`: general `ALL` consumer contract.
100
+ - `references/runtime-context.md`: `MIN_API_VERSION`, `ORG_API_VERSION`, and evidence-version handling.
101
+ - `references/conjunction-compiler.md`: deterministic bucket, index, and custom-conjunction construction.
102
+ - `references/examples/TaggedObjectAccess/`: semantic OLS evidence package.
103
+ - `references/examples/FieldReadDeny/`: semantic FLS deny evidence package.
104
+ - `references/examples/LastCharactersFieldMasking/`: semantic field-masking evidence package.
105
+ - `references/examples/PrincipalFieldMatchRLS/`: semantic direct-comparison RLS evidence package.
106
+ - `references/examples/ExistsJoinRLS/`: semantic projection-join RLS evidence package.
253
107
 
254
- ## 9. Output Hygiene — What the Agent Must NOT Say to the User
108
+ The semantic examples are derived from retrieved server output and retain source-org-specific values. Whether a given example also retains the server-managed compatibility flags depends on when it was captured, not on a contract — `TaggedObjectAccess`'s set, for instance, carries only `<label>` and no compatibility flags, while the other four examples do carry them. They prove persisted metadata shapes, not Policy Builder open/save compatibility or a public MDAPI enum contract. Treat them as evidence, not directly deployable templates. Do not copy persisted compatibility fields, IDs, references, or undocumented enum values into authored packages; resolve every org-specific value again, change component identities and requested policy values, and validate the result in the target org.
255
109
 
256
- The agent's user-facing chat response accompanies every generated file. Customers should never see internal engine or implementation details.
110
+ ## Package Contract
257
111
 
258
- - **Do NOT name the internal evaluation engine** in user-facing text — including but not limited to `Cedar`, `policy engine`, `AuthZ engine`, `evaluation engine`, `Rego`, `OPA`, or similar. The customer-facing surface is *Data Governance*, *Policy Builder*, *Data Cloud Governance* — use those terms only.
259
- - **Do NOT emit trailing "How it works at runtime" narratives** that describe evaluation flow, principal-resource matching semantics, or engine-internal condition ordering. The generated file is the artifact; a one-line summary of what deployed is enough. If the user explicitly asks how enforcement works, describe it in product terms (e.g. "Data Governance denies the read when …"), never in engine terms.
260
- - **Do NOT name internal packages, source directories, Java class names, method names, or line-number references** in user-facing text. Internal implementation identifiers are not customer-facing; refer to platform behavior in product terms only ("the server validates …", "Data Governance rejects …").
261
- - **Do NOT explain auto-fill / default-fill / fallback semantics** unless the user asks. Ship the rule; surface constraints only when they affect what the user has to do next (e.g. "the DMO tag must exist before deploy").
112
+ ```text
113
+ <policy>/
114
+ package.xml
115
+ policyRuleDefinitionSets/<setName>.policyRuleDefinitionSet
116
+ policyRuleDefinitions/<ruleName>.policyRuleDefinition
117
+ ```
262
118
 
263
- If the user needs more context, they'll ask — respond then, in product language.
119
+ The rule must contain `<policyRuleDefinitionSetName>` equal to the set filename without its extension. The package must list both metadata types.
264
120
 
265
- ---
121
+ Both the set and the rule take a human-readable `<label>`. The set's `<label>` conventionally matches its developer name (`TaggedObjectAccess`'s set uses `<label>TaggedObjectAccess</label>`); the rule's `<label>` conventionally identifies its position within the set (`TaggedObjectAccess_Rule_1` uses `<label>Rule 1</label>`). This is a plain descriptive label, distinct from the reference-resolution rule against emitting a *resolved-reference* label (see `references/reference-resolution.md`): never substitute a tag/classification/permission's display label for its resolved developer/API name, but the set's and rule's own `<label>` are always fine to author.
266
122
 
267
- ## Reference Docs
123
+ The MD-CRUD path sends each component's XML as `xmlRep` and resolves the API version server-side, so no `package.xml`/manifest `<version>` and no `ORG_API_VERSION` interpolation are required. The `package.xml` shown above and the `<version>{API_VERSION}</version>` placeholder are retained only for the eval fixtures and as the logical component set. Historical evidence versions are provenance only. Never modify the caller's `sfdx-project.json` to set an operation-specific version.
268
124
 
269
- | Detail | File |
270
- |--------|------|
271
- | Full path enums, operators, value sets, JSON expressions (PROJECTION / ARGLIST / SOQLTARGETLISTEXPR) | [`references/policy-schema-full.md`](references/policy-schema-full.md) |
272
- | Copy-paste templates — index at [`references/templates.md`](references/templates.md); per-variant: [`templates-access.md`](references/templates-access.md), [`templates-record.md`](references/templates-record.md), [`templates-transform.md`](references/templates-transform.md), [`templates-advanced.md`](references/templates-advanced.md) |
273
- | Full UI-compatibility checklist, round-trip rules, operator/path support matrix | [`references/ui-compatibility.md`](references/ui-compatibility.md) |
125
+ Do not author `builderCompatible` or `builderValidated`. Both appear in persisted metadata, and neither is part of the generated package contract until a separately defined Policy Builder validation workflow exists.
@@ -0,0 +1,47 @@
1
+ # Condition Model
2
+
3
+ Each `<conditions>` element is a comparison:
4
+
5
+ ```text
6
+ condition = left operand + operator + right operand
7
+ ```
8
+
9
+ The XML does not contain literal `<left>` or `<right>` elements. The operand type determines which elements represent each side.
10
+
11
+ | Logical part | XML representation |
12
+ |---|---|
13
+ | Resource left operand | `resourcePath`, optionally `resourceExpression` |
14
+ | Principal left operand | `principalPath`, optionally `principalExpression` |
15
+ | Context left operand | `contextPath` |
16
+ | Comparison | `operator` |
17
+ | Right reference or literal | `policyRuleValueSet` |
18
+ | Right record/domain value | `valueDomain` |
19
+ | Right principal-derived value | `valuePrincipalPath` |
20
+ | Clause polarity | `clause` inside the matching WHEN/UNLESS wrapper |
21
+
22
+ Every condition must be constructed in this order:
23
+
24
+ 1. Select the wrapper: `whenPolicyRuleDefinitionClauseConjunction` or `unlessPolicyRuleDefinitionClauseConjunction`.
25
+ 2. Set `<clause>` to `WHEN` or `UNLESS` to match the wrapper.
26
+ 3. Select the left path. Most conditions use one of `resourcePath`, `principalPath`, or `contextPath`; a record-field-to-principal comparison uses both `resourcePath=RECORDFIELD` and a principal expression.
27
+ 4. Add a `resourceExpression` or `principalExpression` if the selected left operand requires an expression.
28
+ 5. Select the operator valid for that operand.
29
+ 6. Add the right-side representation required by the shape. Most conditions use one of `policyRuleValueSet`, `valueDomain`, or `valuePrincipalPath`; a record-field-to-principal comparison uses `valueDomain` and `valuePrincipalPath` together.
30
+
31
+ Example: principal has a permission.
32
+
33
+ ```xml
34
+ <conditions>
35
+ <clause>WHEN</clause>
36
+ <operator>CONTAINS_ANY</operator>
37
+ <policyRuleValueSet>
38
+ <valueReference>cust_perm1</valueReference>
39
+ <valueReferenceType>CUSTOM_PERMISSION</valueReferenceType>
40
+ </policyRuleValueSet>
41
+ <principalPath>ASSIGNED_PERMISSIONS_PATH</principalPath>
42
+ </conditions>
43
+ ```
44
+
45
+ This means: left operand `principal.assignedPermissions`, operator `CONTAINS_ANY`, right operand custom permission `cust_perm1`.
46
+
47
+ For FLS and masking, condition 1 must be `resourcePath=ENTITYTYPE`, `operator=IS`, and `valueText=FIELD`. OLS instead begins with two entity-type conditions for `OBJECT` and `FIELD`, grouped with `OR`.