Configures the Incident Priority Matrix for Salesforce ITSM through the sf CLI — enabling or disabling the matrix, shaping the Impact x Urgency grid that derives Priority on Incident records, toggling the manual-override preference, and reading or setting the default fallback priority. Reads every value before writing, is idempotent, and requires explicit user confirmation before any mutation. Use when the user wants to view, enable, disable, set up, seed, add to, change, or remove priority matrix configuration for Incident records, change the default incident priority, or asks about incident priority setup, impact/urgency mapping, override, or the ITSM incident priority matrix. DO NOT TRIGGER for Problem or ChangeRequest priority matrices, Case priority fields, standard Priority picklists outside ITSM, SLA or milestone configuration, or enabling Incident Management itself (use the service-itsm-incident-mgmt-configure skill).
Configures the Incident Priority Matrix for Salesforce ITSM — the grid that derives an Incident's Priority from its Impact and Urgency. Covers viewing the matrix, enabling / disabling it, adding / changing / removing / seeding cells, toggling the manual-override preference, and reading / setting the default (fallback) priority.
Every read and write dispatches through the sf CLI, so this skill works on any org with the Incident Management license enabled.
Writes are idempotent (skipped when the current state already matches the target), the skill always reads before it writes, and an explicit confirm-to-write checkpoint is required before any mutation.
Scope
In scope (Incident only): view the matrix; enable / disable it; add, change, remove, or
seed matrix cells; toggle manual override; read / set the default (fallback) priority.
Out of scope: Problem and ChangeRequest matrices; non-ITSM Priority pickers;
SLA / milestone / entitlement setup; enabling Incident Management itself. If the user
asks about Problem or ChangeRequest, stop and say so.
Preconditions
sf CLI ≥ 2.60 (verify with sf --version).
The target org is authenticated with sf — one of sf org list should show it as Connected.
Incident Management is enabled on the org — the master pref for the Service Cloud ITSM
Incident feature (Setup Discovery apiName = service-cloud-itsm-incident). Read directly
at preflight time via GET /services/data/v67.0/connect/setup/discovery/features and
filter to apiName == "service-cloud-itsm-incident" (the setup-org-preferences endpoint
for the master is not exposed on this surface — IncidentMgmtEnabled /
ITSMIncidentMgmtEnabled both 404). If status != "ENABLED", delegate to
service-itsm-incident-mgmt-configure inline to enable it (that skill runs its own
read-before-write + confirm-to-write against the same route), then resume Phase 1.
The calling user has CustomizeApplication (View Setup + Setup Admin).
If any precondition is unmet, the CLI surfaces the raw error verbatim — do not fabricate state,
surface the raw error and stop.
Routes at a glance
Every route is called through the sf CLI. Full method / path / body / response
details, the picklist extraction recipe, and gotchas live in references/sf-cli-invocation.md.
Concern
Transport
HTTP status
Master Incident Mgmt pref (read)
sf api request rest GET on /services/data/v67.0/connect/setup/discovery/features, filter apiName == "service-cloud-itsm-incident" for status
200
Matrix enable flag (read/write)
sf api request rest on /services/data/v67.0/setup/org/preferences/IncPriorityMatrixEnabled
200
Manual override (read/write)
sf api request rest on /services/data/v67.0/setup/org/preferences/IncPriorityOverrideEnabled
200
Matrix rows (read)
sf data query --use-tooling-api on ServiceOpPriorityConfig
200
Matrix rows (add)
sf api request rest POST on /services/data/v67.0/tooling/sobjects/ServiceOpPriorityConfig
201
Matrix rows (change)
sf api request rest PATCH on /services/data/v67.0/tooling/sobjects/ServiceOpPriorityConfig/<Id>
204
Matrix rows (remove)
sf data delete record --use-tooling-api on ServiceOpPriorityConfig
200
Default fallback priority (read)
sf api request rest GET on /services/data/v67.0/tooling/query/?q=...StandardValueSet...
200
Default fallback priority (write)
sf project retrieve start + edit + sf project deploy start on StandardValueSet:IncidentPriority
deploy Succeeded
Picklist values (Incident)
sf api request rest GET on /services/data/v67.0/sobjects/Incident/describe
200
Salesforce Go step "Done" (write, after a mutation)
sf api request rest PUT on /services/data/v67.0/connect/setup/discovery/feature/service-cloud-itsm-incident/configuration/step/definePriorityMatrix/progress
200
Path prefixes are load-bearing — do NOT strip them. Setup Connect API paths MUST start with
/services/data/v67.0/. Tooling REST paths MUST start with /services/data/v67.0/tooling/.
Clarifying Questions
Ask only what you cannot infer:
Which org?sf CLI alias or username (--target-org <alias>). Default: the org's default target.
What operation? View; enable / disable the matrix; toggle manual override; set the default priority; add / change / remove a cell; seed a full matrix.
For add / change: the Impact + Urgency coordinates and the resulting Priority (validated against the fetched picklist values).
For set-default-priority: the target Priority value. If the user did not name one, dispatch AskUserQuestion with the org's active Incident.Priority picklist values as options — never guess.
Workflow
All steps are sequential. Always read before you write. All calls go through sf CLI.
Phase 0 — Reuse what the session already knows
Each Phase 1 / Phase 2 read below carries a skip-if-already-known clause. Before
calling any sf command, check whether an earlier turn in this session already produced
the same fact from a successful sf invocation tied to the current --target-org
(a prior run of this skill, or an earlier sf call in the same conversation). Session
context here is per --target-org <alias>, so a different alias is a different session.
An explicit user statement is NOT cache-eligible — the picklist values, pref
booleans, matrix rows, and fallback priority all drive client-side validation and
duplicate prevention on Phase-4 mutations, so a mistaken or stale user assertion can
bypass those safeguards and create invalid or duplicate rows. When the only source is
a user statement (or you cannot identify a specific prior sf response), re-read.
sf --version — if the CLI version was already reported this session, skip step 1.
Incident describe (active Impact / Urgency / Priority picklists) — if the
Incident describe was already read for the current --target-org this session and the
three picklists are in context, skip step 2 and reuse them.
IncPriorityMatrixEnabled / IncPriorityOverrideEnabled pref values — if either
was already read this session AND has not been PATCHed since, skip its Phase-2 read.
ServiceOpPriorityConfig rows — if the current-org Incident rows were already
read this session AND no POST / PATCH / delete on ServiceOpPriorityConfig has
been dispatched since, skip step 5 and reuse the row list.
StandardValueSet:IncidentPriority default — if the fallback priority was already
read this session AND no StandardValueSet:IncidentPriority deploy has run since,
skip step 6.
When in doubt, re-check. Skip only when the fact is unambiguously in context, the
--target-org alias is unchanged, and no Phase-4 write since (a pref PATCH, a
ServiceOpPriorityConfig POST/PATCH/delete, or a StandardValueSet:IncidentPriority
deploy) could have invalidated it. A wrong skip on a live org is worse than a re-read.
Phase 1 — Preflight
(Skip if sf --version was already reported this session — see Phase 0.)sf --version to confirm the CLI is available.
Master Incident Management pref — direct read(Skip only if the master pref was
already read this session for the current --target-org AND the value was ENABLED
AND no write elsewhere in this session could have flipped it — see Phase 0.)sf api request rest "/services/data/v67.0/connect/setup/discovery/features" --method GET --target-org <alias>. Parse the response and filter the features[] array to the element where apiName == "service-cloud-itsm-incident"; read its status field. If status == "ENABLED", proceed to step 3. If status != "ENABLED", delegate to service-itsm-incident-mgmt-configure inline to enable the master pref (that skill runs its own confirm-to-write against the same route), then re-read this step to verify status == "ENABLED" before continuing. If the delegation is declined by the user, halt — Priority Matrix cannot function while the master is off. This is a direct read of the master pref, not a proxy — the Incident describe check that follows is a secondary sanity check, not the master-state signal.
(Skip if the Incident describe for the current --target-org — including active Impact / Urgency / Priority picklists — is already in context this session — see Phase 0.)sf api request rest "/services/data/v67.0/sobjects/Incident/describe" --method GET --target-org <alias>. A 200 with Impact / Urgency / Priority picklist fields is a secondary sanity check. Extract active picklist values for later validation. If the describe response is large, dispatch a subagent (haiku tier) to extract just the three picklists.
Phase 2 — Show current state (read-only)
Dispatch these reads (all expected to return 200):
(Skip if IncPriorityMatrixEnabled for the current --target-org was already read this session AND has not been PATCHed since — see Phase 0.)sf api request rest "/services/data/v67.0/setup/org/preferences/IncPriorityMatrixEnabled" --method GET --target-org <alias> — matrix enable flag. Body: {"isPreferenceEnabled": <bool>}.
(Skip if IncPriorityOverrideEnabled for the current --target-org was already read this session AND has not been PATCHed since — see Phase 0.)sf api request rest "/services/data/v67.0/setup/org/preferences/IncPriorityOverrideEnabled" --method GET --target-org <alias> — manual-override flag. Same body shape.
(Skip if the Incident ServiceOpPriorityConfig rows for the current --target-org were already read this session AND no POST / PATCH / delete on this SObject has been dispatched since — see Phase 0.) Matrix rows — sf data query --use-tooling-api --target-org <alias> --query "SELECT Id, DeveloperName, ReferenceObject, Urgency, Impact, Priority FROM ServiceOpPriorityConfig WHERE ReferenceObject = 'Incident'". Returns zero or more rows. DeveloperName is required so the add step can derive a fresh unique suffix.
(Skip if the StandardValueSet:IncidentPriority default was already read this session AND no StandardValueSet:IncidentPriority deploy has run since — see Phase 0.) Default fallback priority — sf api request rest "/services/data/v67.0/tooling/query/?q=SELECT+Id,MasterLabel,Metadata+FROM+StandardValueSet+WHERE+MasterLabel='IncidentPriority'" --method GET --target-org <alias>. Read records[0].Metadata.standardValue, find the entry with default: true, take its valueName — that is the fallback priority.
Format the rows as an Impact × Urgency grid (see examples/render-matrix.md). Steps 3–6 together are the "view" operation and the before-snapshot.
Duplicate-coordinate detection (load-bearing for Change / Remove): group the Phase-2 rows by (ReferenceObject, Urgency, Impact). If any group has more than one row, the matrix already contains duplicates (the server does not enforce uniqueness). For every operation whose target coordinate is duplicated, halt Phase 3 for that concern — do NOT ask the user to confirm a Change or Remove until they either name an explicit Id or approve a consolidation plan (see Phase 4 → Change a cell and Phase 4 → Remove a cell). Add is unaffected — the Phase-4 add path already refuses any coordinate already present in the snapshot.
Phase 3 — Confirm target (AskUserQuestion, REQUIRED before any write)
Present the intended change as (Concern: <before> → <after>) and require an explicit "yes" via AskUserQuestion. Proceed to Phase 4 only on explicit "yes". On "no", stop and report the current state without writing.
Phase 4 — Apply the change (skip for view-only)
Read the current value of the same concern first (Phase 2 covers this), confirm the target with the user (Phase 3), then dispatch. Payload shapes and full CLI invocations for every operation live in examples/matrix-operations.md.
Enable / disable the matrix — sf api request rest PATCH on IncPriorityMatrixEnabled with body {"desiredState": <bool>}. PATCH response echoes {"isPreferenceEnabled": <bool>}; no separate re-read needed.
Toggle manual override — sf api request rest PATCH on IncPriorityOverrideEnabled with body {"desiredState": <bool>}. Does not touch matrix rows or the default priority.
Add a cell — sf api request rest POST on /services/data/v67.0/tooling/sobjects/ServiceOpPriorityConfig with body {"ReferenceObject": "Incident", "Urgency": "<val>", "Impact": "<val>", "Priority": "<val>", "DeveloperName": "<unique>", "MasterLabel": "<same>"}. Payload must have ReferenceObject == "Incident" — the SObject is shared with Problem / ChangeRequest and the server accepts any string. Validate every Urgency / Impact / Priority against the fetched picklists first — the Tooling endpoint does NOT enforce picklist validation. Deduplicate against the Phase-2 snapshot: the server does NOT reject duplicates on (ReferenceObject, Urgency, Impact), so a second POST on the same coordinate silently persists as a second row and the runtime picks between them non-deterministically.
Change a cell — read Phase-2 rows, find the row(s) matching (ReferenceObject=Incident, Urgency, Impact). If exactly one row matches, sf api request rest PATCH on /services/data/v67.0/tooling/sobjects/ServiceOpPriorityConfig/<Id> with body {"Priority": "<new val>"}. If zero rows match, this is an add — not a change; surface and ask. If more than one row matches (duplicates were detected in Phase 2), do NOT dispatch — report the duplicate rows with their Id / DeveloperName / current Priority, and require the user to either name the exact Id to change or approve a consolidation plan (delete the extras, then change the survivor).
Remove a cell — read Phase-2 rows, find the row(s) matching (ReferenceObject=Incident, Urgency, Impact). If exactly one row matches, sf data delete record --sobject ServiceOpPriorityConfig --record-id <Id> --use-tooling-api --target-org <alias>. If zero rows match, short-circuit with "nothing to remove". If more than one row matches, do NOT dispatch — report the duplicates and require the user to either name the exact Id(s) to remove or explicitly confirm "remove all rows at this coordinate".
Seed a full matrix — see examples/seed-full-matrix.md. Validate values first, then POST each row.
Set the default fallback priority — sf project retrieve start --metadata "StandardValueSet:IncidentPriority" --target-org <alias>, edit the file to set <default>true</default> on the target value and <default>false</default> on every other, then sf project deploy start --metadata "StandardValueSet:IncidentPriority" --target-org <alias> --wait 10. Verify with Succeeded in the deploy result.
Phase 5 — Verify and present
Re-read the concern that was mutated (matrix rows via Tooling SOQL; default priority via StandardValueSet query; prefs are echoed on PATCH response). If the observed state does not match the requested state, treat it as a failed write and report the raw server response verbatim.
Mark the Salesforce Go step Done — only if a Phase-4 functional write actually landed. The "Define Priority Matrix" step is user-override: its checkmark is not derived from org state, so configuring the matrix alone never flips it — completion must be written. After step 7 verifies the write, PUT the completion once (references/sf-cli-invocation.md route 10; body {"isComplete": true}, flag REQUIRED). It rides on the Phase-3 confirmation — no separate AskUserQuestion. Skip entirely on view-only reads and idempotent no-ops.
Present before/after (Impact × Urgency grid via examples/render-matrix.md) plus a one-line summary (e.g. Incident matrix: High/High → Critical added). Matrix changes affect only Incidents created after the write; disabling the matrix does not clear stored rows or the default priority.
Rules / Constraints
Constraint
Rationale
All operations run through sf CLI
Works on any org with Incident Management enabled; requires no additional setup
Always API v67.0 minimum
The Setup Connect API pref routes require v67+
Read live state before writing
The Phase-2 snapshot is the source of truth for the confirmation prompt, the idempotency check, and the Phase-5 verify
REQUIRED confirm-to-write checkpoint before any mutation
Toggling prefs or changing matrix rows mutates org state; user must approve the exact plan
Idempotent — skip the write when the current state already matches the requested state
Avoids no-op writes; see references/sf-cli-invocation.md for the exact match rule per concern
Validate every Impact, Urgency, Priority against the org's live picklist before dispatch
The Tooling REST endpoint does NOT enforce picklist validation; the runtime matrix evaluator does. Skipping this validation lets garbage rows into the matrix
Deduplicate rows client-side against the Phase-2 snapshot before add
The server does NOT enforce (ReferenceObject, Urgency, Impact) uniqueness — a second POST on the same coordinate persists as a separate row. Client-side dedup is the only guard against duplicate cells.
Refuse any ReferenceObject other than Incident (Problem, ChangeRequest, anything else)
ServiceOpPriorityConfig is shared with the Problem / ChangeRequest matrices at the wire level — the server accepts any ReferenceObject string. Scope to Incident is skill-enforced only.
On Change / Remove, if the target coordinate resolves to more than one row, do NOT dispatch — require an explicit Id or a confirmed consolidation plan
The server allows duplicate (ReferenceObject, Urgency, Impact) rows. Picking "the row Id" arbitrarily would mutate one duplicate and leave the other in place, keeping the matrix non-deterministic.
Report exact error text from the CLI response
The CLI surfaces the underlying error message verbatim
After a functional write, PUT the Salesforce Go step-progress completion (route 10); skip on view / no-op
The "Define Priority Matrix" step is user-override — its checkmark isn't derived from org state, so config writes alone leave the Go checklist stuck
Verification Checklist
Before reporting completion of any mutation, confirm each of the following. If any item is unchecked, do not report success — surface what is missing.
Phase 1 preflight (sf api request rest on Incident describe) returned 200 with active Impact / Urgency / Priority picklists; if 404, the raw error was surfaced and the run halted.
Phase 2 read against every concern the write plans to touch returned 200 (or a raw error was surfaced) and each observed value was recorded as the "before" state. For Change / Remove, the Phase-2 rows were grouped by (ReferenceObject, Urgency, Impact) and any duplicate coordinates on the mutation target were surfaced to the user — no Change / Remove was dispatched until an explicit Id or a confirmed consolidation plan resolved the duplication.
Phase 3 confirm-to-write presented (<concern>: <current> → <requested>) via AskUserQuestion and the user replied with an explicit "yes" — no write dispatched on any other response (silence, "maybe", "looks good", implicit approval).
Idempotency: if the current state already matched the requested state, Phase 4 was skipped for that concern and reported as an idempotent no-op — no write was dispatched.
Every Impact, Urgency, Priority in any add / change payload was validated against the Phase-1 picklist values before dispatch. Duplicates on (ReferenceObject, Urgency, Impact) were caught client-side against the Phase-2 snapshot — the server does NOT reject duplicates. Every add payload had ReferenceObject == "Incident".
Phase 4 writes used the exact CLI invocations from references/sf-cli-invocation.md; on any 4xx / 5xx (or non-Succeeded deploy), the raw response was surfaced and the run halted.
Phase 5 verify re-read the affected concerns; any diff was reported as write FAILED — server state differs from request with the raw response.
If a Phase-4 functional write landed, the Go step-progress completion PUT (route 10) was sent after verify. On view-only reads and idempotent no-ops, no completion PUT was dispatched.
The final report gave a before/after with the Impact × Urgency grid and a one-line summary.
Reference File Index
File
When to read
references/sf-cli-invocation.md
Exact sf CLI invocations, response envelopes, picklist extraction, idempotency rules, and gotchas
examples/render-matrix.md
Impact × Urgency grid layout
examples/matrix-operations.md
Full CLI-invocation templates for enable, override, default, add / change / remove
examples/seed-full-matrix.md
Seed a full matrix (validate picklist values first)
1---2name: service-itsm-incident-priority-configure3description: Configures the Incident Priority Matrix for Salesforce ITSM through the sf CLI — enabling or disabling the matrix, shaping the Impact x Urgency grid that derives Priority on Incident records, toggling the manual-override preference, and reading or setting the default fallback priority. Reads every value before writing, is idempotent, and requires explicit user confirmation before any mutation. Use when the user wants to view, enable, disable, set up, seed, add to, change, or remove priority matrix configuration for Incident records, change the default incident priority, or asks about incident priority setup, impact/urgency mapping, override, or the ITSM incident priority matrix. DO NOT TRIGGER for Problem or ChangeRequest priority matrices, Case priority fields, standard Priority picklists outside ITSM, SLA or milestone configuration, or enabling Incident Management itself (use the service-itsm-incident-mgmt-configure skill).4---56# Configuring the Incident Priority Matrix (sf CLI)
78Configures the **Incident Priority Matrix** for Salesforce ITSM — the grid that derives an Incident's **Priority** from its **Impact** and **Urgency**. Covers viewing the matrix, enabling / disabling it, adding / changing / removing / seeding cells, toggling the manual-override preference, and reading / setting the default (fallback) priority.
910Every read and write dispatches through the **`sf` CLI**, so this skill works on any org with the Incident Management license enabled.
1112Writes are **idempotent** (skipped when the current state already matches the target), the skill always **reads before it writes**, and an explicit **confirm-to-write** checkpoint is required before any mutation.
1314## Scope
1516- **In scope** (Incident only): view the matrix; enable / disable it; add, change, remove, or
17 seed matrix cells; toggle manual override; read / set the default (fallback) priority.
18- **Out of scope**: `Problem` and `ChangeRequest` matrices; non-ITSM Priority pickers;
19 SLA / milestone / entitlement setup; enabling Incident Management itself. If the user
20 asks about `Problem` or `ChangeRequest`, stop and say so.
2122---
2324## Preconditions
25261. `sf` CLI ≥ 2.60 (verify with `sf --version`).
272. The target org is authenticated with `sf` — one of `sf org list` should show it as `Connected`.
283. Incident Management is enabled on the org — the master pref for the Service Cloud ITSM
29 Incident feature (Setup Discovery `apiName = service-cloud-itsm-incident`). Read directly
30 at preflight time via `GET /services/data/v67.0/connect/setup/discovery/features` and
31 filter to `apiName == "service-cloud-itsm-incident"` (the setup-org-preferences endpoint
32 for the master is not exposed on this surface — `IncidentMgmtEnabled` /
33 `ITSMIncidentMgmtEnabled` both 404). If `status != "ENABLED"`, delegate to
34 `service-itsm-incident-mgmt-configure` inline to enable it (that skill runs its own
35 read-before-write + confirm-to-write against the same route), then resume Phase 1.
364. The calling user has `CustomizeApplication` (View Setup + Setup Admin).
3738If any precondition is unmet, the CLI surfaces the raw error verbatim — **do not fabricate state,
39surface the raw error and stop.**
4041---
4243## Routes at a glance
4445Every route is called through the `sf` CLI. Full method / path / body / response
46details, the picklist extraction recipe, and gotchas live in `references/sf-cli-invocation.md`.
4748| Concern | Transport | HTTP status |
49|---------|-----------|-------------|
50| Master Incident Mgmt pref (read) | `sf api request rest` GET on `/services/data/v67.0/connect/setup/discovery/features`, filter `apiName == "service-cloud-itsm-incident"` for `status` | 200 |
51| Matrix enable flag (read/write) | `sf api request rest` on `/services/data/v67.0/setup/org/preferences/IncPriorityMatrixEnabled` | 200 |
52| Manual override (read/write) | `sf api request rest` on `/services/data/v67.0/setup/org/preferences/IncPriorityOverrideEnabled` | 200 |
53| Matrix rows (read) | `sf data query --use-tooling-api` on `ServiceOpPriorityConfig` | 200 |
54| Matrix rows (add) | `sf api request rest` POST on `/services/data/v67.0/tooling/sobjects/ServiceOpPriorityConfig` | 201 |
55| Matrix rows (change) | `sf api request rest` PATCH on `/services/data/v67.0/tooling/sobjects/ServiceOpPriorityConfig/<Id>` | 204 |
56| Matrix rows (remove) | `sf data delete record --use-tooling-api` on `ServiceOpPriorityConfig` | 200 |
57| Default fallback priority (read) | `sf api request rest` GET on `/services/data/v67.0/tooling/query/?q=...StandardValueSet...` | 200 |
58| Default fallback priority (write) | `sf project retrieve start` + edit + `sf project deploy start` on `StandardValueSet:IncidentPriority` | deploy Succeeded |
59| Picklist values (Incident) | `sf api request rest` GET on `/services/data/v67.0/sobjects/Incident/describe` | 200 |
60| Salesforce Go step "Done" (write, after a mutation) | `sf api request rest` PUT on `/services/data/v67.0/connect/setup/discovery/feature/service-cloud-itsm-incident/configuration/step/definePriorityMatrix/progress` | 200 |
6162**Path prefixes are load-bearing — do NOT strip them.** Setup Connect API paths MUST start with
63`/services/data/v67.0/`. Tooling REST paths MUST start with `/services/data/v67.0/tooling/`.
6465---
6667## Clarifying Questions
6869Ask only what you cannot infer:
7071- **Which org?** `sf` CLI alias or username (`--target-org <alias>`). Default: the org's default target.
72- **What operation?** View; enable / disable the matrix; toggle manual override; set the default priority; add / change / remove a cell; seed a full matrix.
73- **For add / change:** the `Impact` + `Urgency` coordinates and the resulting `Priority` (validated against the fetched picklist values).
74- **For set-default-priority:** the target Priority value. If the user did **not** name one, dispatch `AskUserQuestion` with the org's active `Incident.Priority` picklist values as options — never guess.
7576---
7778## Workflow
7980All steps are sequential. **Always read before you write.** All calls go through `sf` CLI.
8182### Phase 0 — Reuse what the session already knows
8384Each Phase 1 / Phase 2 read below carries a **skip-if-already-known** clause. Before
85calling any `sf` command, check whether an earlier turn in this session already produced
86the same fact **from a successful `sf` invocation tied to the current `--target-org`**
87(a prior run of this skill, or an earlier `sf` call in the same conversation). Session
88context here is per `--target-org <alias>`, so a different alias is a different session.
89**An explicit user statement is NOT cache-eligible** — the picklist values, pref
90booleans, matrix rows, and fallback priority all drive client-side validation and
91duplicate prevention on Phase-4 mutations, so a mistaken or stale user assertion can
92bypass those safeguards and create invalid or duplicate rows. When the only source is
93a user statement (or you cannot identify a specific prior `sf` response), re-read.
9495- **`sf --version`** — if the CLI version was already reported this session, skip step 1.
96- **Incident `describe` (active `Impact` / `Urgency` / `Priority` picklists)** — if the
97 Incident describe was already read for the current `--target-org` this session and the
98 three picklists are in context, skip step 2 and reuse them.
99- **`IncPriorityMatrixEnabled` / `IncPriorityOverrideEnabled` pref values** — if either
100 was already read this session AND has not been PATCHed since, skip its Phase-2 read.
101- **`ServiceOpPriorityConfig` rows** — if the current-org Incident rows were already
102 read this session AND no `POST` / `PATCH` / `delete` on `ServiceOpPriorityConfig` has
103 been dispatched since, skip step 5 and reuse the row list.
104- **`StandardValueSet:IncidentPriority` default** — if the fallback priority was already
105 read this session AND no `StandardValueSet:IncidentPriority` deploy has run since,
106 skip step 6.
107108**When in doubt, re-check.** Skip only when the fact is unambiguously in context, the
109`--target-org` alias is unchanged, and no Phase-4 write since (a pref PATCH, a
110`ServiceOpPriorityConfig` POST/PATCH/delete, or a `StandardValueSet:IncidentPriority`
111deploy) could have invalidated it. A wrong skip on a live org is worse than a re-read.
112113### Phase 1 — Preflight
1141151. *(Skip if `sf --version` was already reported this session — see Phase 0.)* `sf --version` to confirm the CLI is available.
1162. **Master Incident Management pref — direct read** *(Skip only if the master pref was
117 already read this session for the current `--target-org` AND the value was `ENABLED`
118 AND no write elsewhere in this session could have flipped it — see Phase 0.)* `sf api request rest "/services/data/v67.0/connect/setup/discovery/features" --method GET --target-org <alias>`. Parse the response and filter the `features[]` array to the element where `apiName == "service-cloud-itsm-incident"`; read its `status` field. If `status == "ENABLED"`, proceed to step 3. **If `status != "ENABLED"`, delegate to `service-itsm-incident-mgmt-configure` inline to enable the master pref** (that skill runs its own confirm-to-write against the same route), then re-read this step to verify `status == "ENABLED"` before continuing. If the delegation is declined by the user, halt — Priority Matrix cannot function while the master is off. This is a **direct read of the master pref**, not a proxy — the Incident describe check that follows is a secondary sanity check, not the master-state signal.
1193. *(Skip if the Incident describe for the current `--target-org` — including active `Impact` / `Urgency` / `Priority` picklists — is already in context this session — see Phase 0.)* `sf api request rest "/services/data/v67.0/sobjects/Incident/describe" --method GET --target-org <alias>`. A **200** with `Impact` / `Urgency` / `Priority` picklist fields is a secondary sanity check. Extract active picklist values for later validation. If the describe response is large, dispatch a subagent (haiku tier) to extract just the three picklists.
120121### Phase 2 — Show current state (read-only)
122123Dispatch these reads (all expected to return 200):
1241253. *(Skip if `IncPriorityMatrixEnabled` for the current `--target-org` was already read this session AND has not been PATCHed since — see Phase 0.)* `sf api request rest "/services/data/v67.0/setup/org/preferences/IncPriorityMatrixEnabled" --method GET --target-org <alias>` — matrix enable flag. Body: `{"isPreferenceEnabled": <bool>}`.
1264. *(Skip if `IncPriorityOverrideEnabled` for the current `--target-org` was already read this session AND has not been PATCHed since — see Phase 0.)* `sf api request rest "/services/data/v67.0/setup/org/preferences/IncPriorityOverrideEnabled" --method GET --target-org <alias>` — manual-override flag. Same body shape.
1275. *(Skip if the Incident `ServiceOpPriorityConfig` rows for the current `--target-org` were already read this session AND no POST / PATCH / delete on this SObject has been dispatched since — see Phase 0.)* Matrix rows — `sf data query --use-tooling-api --target-org <alias> --query "SELECT Id, DeveloperName, ReferenceObject, Urgency, Impact, Priority FROM ServiceOpPriorityConfig WHERE ReferenceObject = 'Incident'"`. Returns zero or more rows. `DeveloperName` is required so the add step can derive a fresh unique suffix.
1286. *(Skip if the `StandardValueSet:IncidentPriority` default was already read this session AND no `StandardValueSet:IncidentPriority` deploy has run since — see Phase 0.)* Default fallback priority — `sf api request rest "/services/data/v67.0/tooling/query/?q=SELECT+Id,MasterLabel,Metadata+FROM+StandardValueSet+WHERE+MasterLabel='IncidentPriority'" --method GET --target-org <alias>`. Read `records[0].Metadata.standardValue`, find the entry with `default: true`, take its `valueName` — that is the fallback priority.
129130Format the rows as an Impact × Urgency grid (see `examples/render-matrix.md`). Steps 3–6 together are the "view" operation and the before-snapshot.
131132**Duplicate-coordinate detection (load-bearing for Change / Remove):** group the Phase-2 rows by `(ReferenceObject, Urgency, Impact)`. If any group has more than one row, the matrix already contains duplicates (the server does not enforce uniqueness). For every operation whose target coordinate is duplicated, halt Phase 3 for that concern — do NOT ask the user to confirm a Change or Remove until they either name an explicit `Id` or approve a consolidation plan (see `Phase 4 → Change a cell` and `Phase 4 → Remove a cell`). Add is unaffected — the Phase-4 add path already refuses any coordinate already present in the snapshot.
133134### Phase 3 — Confirm target (`AskUserQuestion`, REQUIRED before any write)
135136Present the intended change as `(Concern: <before> → <after>)` and require an explicit "yes" via `AskUserQuestion`. Proceed to Phase 4 **only** on explicit "yes". On "no", stop and report the current state without writing.
137138### Phase 4 — Apply the change (skip for view-only)
139140Read the current value of the same concern first (Phase 2 covers this), confirm the target with the user (Phase 3), then dispatch. Payload shapes and full CLI invocations for every operation live in `examples/matrix-operations.md`.
141142- **Enable / disable the matrix** — `sf api request rest` PATCH on `IncPriorityMatrixEnabled` with body `{"desiredState": <bool>}`. PATCH response echoes `{"isPreferenceEnabled": <bool>}`; no separate re-read needed.
143- **Toggle manual override** — `sf api request rest` PATCH on `IncPriorityOverrideEnabled` with body `{"desiredState": <bool>}`. Does **not** touch matrix rows or the default priority.
144- **Add a cell** — `sf api request rest` POST on `/services/data/v67.0/tooling/sobjects/ServiceOpPriorityConfig` with body `{"ReferenceObject": "Incident", "Urgency": "<val>", "Impact": "<val>", "Priority": "<val>", "DeveloperName": "<unique>", "MasterLabel": "<same>"}`. Payload must have `ReferenceObject == "Incident"` — the SObject is shared with Problem / ChangeRequest and the server accepts any string. Validate every `Urgency` / `Impact` / `Priority` against the fetched picklists first — the Tooling endpoint does NOT enforce picklist validation. Deduplicate against the Phase-2 snapshot: the server does NOT reject duplicates on `(ReferenceObject, Urgency, Impact)`, so a second POST on the same coordinate silently persists as a second row and the runtime picks between them non-deterministically.
145- **Change a cell** — read Phase-2 rows, find the row(s) matching `(ReferenceObject=Incident, Urgency, Impact)`. If **exactly one row matches**, `sf api request rest` PATCH on `/services/data/v67.0/tooling/sobjects/ServiceOpPriorityConfig/<Id>` with body `{"Priority": "<new val>"}`. If **zero rows match**, this is an add — not a change; surface and ask. If **more than one row matches** (duplicates were detected in Phase 2), do NOT dispatch — report the duplicate rows with their `Id` / `DeveloperName` / current `Priority`, and require the user to either name the exact `Id` to change or approve a consolidation plan (delete the extras, then change the survivor).
146- **Remove a cell** — read Phase-2 rows, find the row(s) matching `(ReferenceObject=Incident, Urgency, Impact)`. If **exactly one row matches**, `sf data delete record --sobject ServiceOpPriorityConfig --record-id <Id> --use-tooling-api --target-org <alias>`. If **zero rows match**, short-circuit with "nothing to remove". If **more than one row matches**, do NOT dispatch — report the duplicates and require the user to either name the exact `Id`(s) to remove or explicitly confirm "remove all rows at this coordinate".
147- **Seed a full matrix** — see `examples/seed-full-matrix.md`. Validate values first, then POST each row.
148- **Set the default fallback priority** — `sf project retrieve start --metadata "StandardValueSet:IncidentPriority" --target-org <alias>`, edit the file to set `<default>true</default>` on the target value and `<default>false</default>` on every other, then `sf project deploy start --metadata "StandardValueSet:IncidentPriority" --target-org <alias> --wait 10`. Verify with `Succeeded` in the deploy result.
149150### Phase 5 — Verify and present
1511527. Re-read the concern that was mutated (matrix rows via Tooling SOQL; default priority via `StandardValueSet` query; prefs are echoed on PATCH response). If the observed state does not match the requested state, treat it as a failed write and report the raw server response verbatim.
1538. **Mark the Salesforce Go step Done — only if a Phase-4 functional write actually landed.** The "Define Priority Matrix" step is user-override: its checkmark is **not** derived from org state, so configuring the matrix alone never flips it — completion must be written. After step 7 verifies the write, PUT the completion once (`references/sf-cli-invocation.md` route 10; body `{"isComplete": true}`, flag REQUIRED). It rides on the Phase-3 confirmation — no separate `AskUserQuestion`. **Skip entirely on view-only reads and idempotent no-ops.**
1549. Present before/after (Impact × Urgency grid via `examples/render-matrix.md`) plus a one-line summary (e.g. `Incident matrix: High/High → Critical added`). Matrix changes affect only Incidents created **after** the write; disabling the matrix does not clear stored rows or the default priority.
155156---
157158## Rules / Constraints
159160| Constraint | Rationale |
161|-----------|-----------|
162| All operations run through `sf` CLI | Works on any org with Incident Management enabled; requires no additional setup |
163| Always API v67.0 minimum | The Setup Connect API pref routes require v67+ |
164| Read live state before writing | The Phase-2 snapshot is the source of truth for the confirmation prompt, the idempotency check, and the Phase-5 verify |
165| **REQUIRED confirm-to-write checkpoint** before any mutation | Toggling prefs or changing matrix rows mutates org state; user must approve the exact plan |
166| Idempotent — skip the write when the current state already matches the requested state | Avoids no-op writes; see `references/sf-cli-invocation.md` for the exact match rule per concern |
167| Validate every `Impact`, `Urgency`, `Priority` against the org's live picklist before dispatch | The Tooling REST endpoint does NOT enforce picklist validation; the runtime matrix evaluator does. Skipping this validation lets garbage rows into the matrix |
168| Deduplicate rows client-side against the Phase-2 snapshot before add | The server does NOT enforce `(ReferenceObject, Urgency, Impact)` uniqueness — a second POST on the same coordinate persists as a separate row. Client-side dedup is the only guard against duplicate cells. |
169| Refuse any `ReferenceObject` other than `Incident` (`Problem`, `ChangeRequest`, anything else) | `ServiceOpPriorityConfig` is shared with the Problem / ChangeRequest matrices at the wire level — the server accepts any `ReferenceObject` string. Scope to `Incident` is skill-enforced only. |
170| On Change / Remove, if the target coordinate resolves to more than one row, do NOT dispatch — require an explicit `Id` or a confirmed consolidation plan | The server allows duplicate `(ReferenceObject, Urgency, Impact)` rows. Picking "the row Id" arbitrarily would mutate one duplicate and leave the other in place, keeping the matrix non-deterministic. |
171| Report exact error text from the CLI response | The CLI surfaces the underlying error message verbatim |
172| After a functional write, PUT the Salesforce Go step-progress completion (route 10); skip on view / no-op | The "Define Priority Matrix" step is user-override — its checkmark isn't derived from org state, so config writes alone leave the Go checklist stuck |
173174---
175176## Verification Checklist
177178Before reporting completion of any mutation, confirm each of the following. If any item is unchecked, do not report success — surface what is missing.
179180- [ ] Phase 1 preflight (`sf api request rest` on Incident describe) returned 200 with active `Impact` / `Urgency` / `Priority` picklists; if 404, the raw error was surfaced and the run halted.
181- [ ] Phase 2 read against every concern the write plans to touch returned 200 (or a raw error was surfaced) and each observed value was recorded as the "before" state. For Change / Remove, the Phase-2 rows were grouped by `(ReferenceObject, Urgency, Impact)` and any duplicate coordinates on the mutation target were surfaced to the user — no Change / Remove was dispatched until an explicit `Id` or a confirmed consolidation plan resolved the duplication.
182- [ ] Phase 3 confirm-to-write presented `(<concern>: <current> → <requested>)` via `AskUserQuestion` and the user replied with an explicit "yes" — no write dispatched on any other response (silence, "maybe", "looks good", implicit approval).
183- [ ] Idempotency: if the current state already matched the requested state, Phase 4 was skipped for that concern and reported as an idempotent no-op — no write was dispatched.
184- [ ] Every `Impact`, `Urgency`, `Priority` in any add / change payload was validated against the Phase-1 picklist values before dispatch. Duplicates on `(ReferenceObject, Urgency, Impact)` were caught client-side against the Phase-2 snapshot — the server does NOT reject duplicates. Every add payload had `ReferenceObject == "Incident"`.
185- [ ] Phase 4 writes used the exact CLI invocations from `references/sf-cli-invocation.md`; on any `4xx` / `5xx` (or non-`Succeeded` deploy), the raw response was surfaced and the run halted.
186- [ ] Phase 5 verify re-read the affected concerns; any diff was reported as `write FAILED — server state differs from request` with the raw response.
187- [ ] If a Phase-4 functional write landed, the Go step-progress completion PUT (route 10) was sent after verify. On view-only reads and idempotent no-ops, no completion PUT was dispatched.
188- [ ] The final report gave a before/after with the Impact × Urgency grid and a one-line summary.
189190---
191192## Reference File Index
193194| File | When to read |
195|------|--------------|
196| `references/sf-cli-invocation.md` | Exact `sf` CLI invocations, response envelopes, picklist extraction, idempotency rules, and gotchas |
197| `examples/render-matrix.md` | Impact × Urgency grid layout |
198| `examples/matrix-operations.md` | Full CLI-invocation templates for enable, override, default, add / change / remove |
199| `examples/seed-full-matrix.md` | Seed a full matrix (validate picklist values first) |
Run npx skillmds@latest add gabrielmoreira/service-itsm-incident-priority-configure in your terminal (requires Node.js), paste this page's agent-chat prompt into Claude, Cursor, or any MCP-connected agent, or download the SKILL.md file and copy it into your agent's skills directory.
Configures the Incident Priority Matrix for Salesforce ITSM through the sf CLI — enabling or disabling the matrix, shaping the Impact x Urgency grid that derives Priority on Incident records, toggling the manual-override preference, and reading or setting the default fallback priority. Reads every value before writing, is idempotent, and requires explicit user confirmation before any mutation. Use when the user wants to view, enable, disable, set up, seed, add to, change, or remove priority matrix configuration for Incident records, change the default incident priority, or asks about incident priority setup, impact/urgency mapping, override, or the ITSM incident priority matrix. DO NOT TRIGGER for Problem or ChangeRequest priority matrices, Case priority fields, standard Priority picklists outside ITSM, SLA or milestone configuration, or enabling Incident Management itself (use the service-itsm-incident-mgmt-configure skill). It is listed under Coding & Dev Tools on SkillMD.
This skill has not completed SkillMD's automated safety review yet. Capability flags: docs only. SkillMD never runs a skill's scripts for you; review the SKILL.md before installing.
This skill is tagged as working with Claude Code, Claude.ai, OpenAI Codex. SKILL.md is an open format, so most agents that read a skills directory can load it too.
Yes. Installing skills from SkillMD is free, and the skill stays under its author's original license.
gabrielmoreira (@gabrielmoreira) published this skill. Their other Agent Skills are listed on their SkillMD profile.