Skip to content
Development
Skill

/platform-policy-rule-generate

Use this skill when authoring PolicyRuleDefinition and PolicyRuleDefinitionSet metadata XML for the Salesforce Enforce-O-Matic MDAPI (Data Cloud governance policies), or when editing *.policyRuleDefinition / *.policyRuleDefinitionSet files. Covers the category decision tree,

From plugin
sf-skills
803161 skills6 agents10 commands3 MCP
Install
$ npx -y skills add forcedotcom/sf-skills --skill platform-policy-rule-generate --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/platform-policy-rule-generate

Context preview

The summary Claude sees to decide when to auto-load this skill.

Use this skill when authoring PolicyRuleDefinition and PolicyRuleDefinitionSet metadata XML for the Salesforce Enforce-O-Matic MDAPI (Data Cloud governance policies), or when editing *.policyRuleDefinition / *.policyRuleDefinitionSet files. Covers the category decision tree,

SKILL.md

platform-policy-rule-generate.SKILL.md
name: platform-policy-rule-generate
description: "Use this skill when authoring PolicyRuleDefinition and PolicyRuleDefinitionSet metadata XML for the Salesforce Enforce-O-Matic MDAPI (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, and validation guardrails. Do NOT use this skill for UserAccessPolicy, AccessPolicy, SharingRules, PermissionSet, or any non-Enforce-O-Matic access-control metadata — those have their own types and live outside the PolicyRuleDefinition schema."
metadata:
  version: "1.0"
  minApiVersion: "64.0"
  cliTools:
    - tool: ["jq"]
      semver: ">=1.6.0"
    - tool: ["sf"]
      semver: ">=2.0.0"

Authoring Policy Rule Definitions

**Gating:** `@WsdlGuard("EnforceOMatic.orgCanUsePolicyRuleMDAPI")` = `OrgPermissions.EnforceOMatic && OrgPermissions.PolicyRuleMDAPI` **Min API version:** 64.0 (66.0 for conditions using `PolicyJsonExpression`)

> **For human maintainers (not the agent):** the Java source-of-truth lives at `enforce-o-matic-impl/java/src/enforce/o/matic/metadata/` and reference fixtures at `enforce-o-matic-impl/test/func/filemetadata/<name>/`. The agent should rely on the templates and reference docs in this skill bundle — those impl paths are not readable from the Vibes/MCP runtime.

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, add a fixture under `test/func/filemetadata/`, or ship a metadata package. The runtime side (RuleProvider, hooks) is out of scope.

---

> **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/`.

1. Package Layout

A deployable package always contains:

<fixture>/
  package.xml
  policyRuleDefinitionSets/<setName>.policyRuleDefinitionSet
  policyRuleDefinitions/<ruleName>.policyRuleDefinition

`package.xml` template (use `<version>[ftest]</version>` for ftests, `64.0` or higher for real orgs):

<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
    <types>
        <members>Rule0</members>
        <name>PolicyRuleDefinition</name>
    </types>
    <types>
        <members>Set1</members>
        <name>PolicyRuleDefinitionSet</name>
    </types>
    <version>64.0</version>
</Package>

---

2. PolicyRuleDefinitionSet Schema

<PolicyRuleDefinitionSet xmlns="http://soap.sforce.com/2006/04/metadata">
    <label>Set1</label>
    <description>Optional free text</description>
    <replicated>false</replicated>             <!-- MinAppVersion 260 -->
    <builderCompatible>true</builderCompatible> <!-- MinAppVersion 262, author-settable -->
    <!-- builderValidated: server-managed — do not set in authored XML -->
</PolicyRuleDefinitionSet>

| Element | Req | Notes | |---------|-----|-------| | `<label>` | yes | Master label. File basename (devName) is the MDAPI identifier, not the label. | | `<description>` | no | Free text. | | `<replicated>` | no | `true` triggers placeholder transformation across companion orgs. Omit for null/false. | | `<builderCompatible>` | no | `true` = rules audited per §7 checklist. `false` = API-only. Omit = unaudited. Informational only — no deploy/runtime effect. | | `<builderValidated>` | no | **Server-managed. Never set in authored XML.** Server overwrites on validation. |

---

3. PolicyRuleDefinition — Core Fields

| Element | Req | Notes | |---------|-----|-------| | `<label>` | yes | MasterLabel. | | `<category>` | yes | See §4. Drives `resourceScopeType` and whether `policyRuleResourceDomains`/`resourceTransform` are required. **Does NOT constrain `effect` outside of TRANSFORM.** | | `<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. | | `<action>` | yes (≥1) | `Read`, `TupleRead`, `Create`, etc. Multiple elements OR-combine. | | `<policyRuleDefinitionSetName>` | yes | Developer name of parent set. | | `<principalScopeType>` | yes | Always `ANY`. | | `<resourceScopeType>` | yes | `ANY`, `FIELD`, `RECORD`, `DATASPACE`, or `SPAN`. Must match category (§4). | | `<principalAuthenticationLevel>` | no | `INTERNAL`, `AUTHENTICATED`, `UNIDENTIFIED`, `IDENTIFIED`. | | `<ruleConsumer>` | no | `ALL`, `DATACLOUD`, `MULESOFT`, `TABLEAU`, `CORE`. | | `<policyRuleResourceDomains>` | no | Required for RECORD (RLS) and FIELD-scope TRANSFORM rules only. Forbidden on ACCESS/GOVERNANCE. | | `<resourceTransform>` | no | Required (and only valid) when `category=TRANSFORM`. | | `<whenPolicyRuleDefinitionClauseConjunction>` | no | WHEN conditions. | | `<unlessPolicyRuleDefinitionClauseConjunction>` | no | UNLESS conditions. Not UI-editable — prefer WHEN + negated operator. |

---

4. Category Decision Tree

**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.**

The **only** Category × Effect rule the platform validates (`enforce-o-matic-api/java/src/enforce/o/matic/api/module/api/RuleBuilder.java`):

  • `effect=Transform` ⇔ `category=TRANSFORM_POLICY_RULE_DEFINITION` (bidirectional; mismatched throws `INVALIDFORCATEGORY`).
  • All other categories (`ACCESS`, `GOVERNANCE`, `RECORD`, `IDENTIFIED_RECORD`) accept either `Permit` or `Forbid`.

> **Note on the platform's auto-fill default:** When `<category>` is omitted from authored XML, the i

Read more
Ships withsf-skills

This repository provides a curated collection of Salesforce agent skills for building applications.

Get the whole plugin

Other skills on sf-skills.