@salesforce/afv-skills 1.58.0 → 1.60.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 (242) hide show
  1. package/package.json +1 -1
  2. package/skills/agentforce-architecture-analyze/SKILL.md +66 -17
  3. package/skills/agentforce-architecture-analyze/assets/cli/show_access_token.yaml +4 -7
  4. package/skills/agentforce-architecture-analyze/references/contract.json +1 -1
  5. package/skills/agentforce-architecture-analyze/scripts/emit_env.py +2 -2
  6. package/skills/agentforce-architecture-analyze/scripts/main.py +40 -44
  7. package/skills/agentforce-architecture-analyze/scripts/rest_client.py +11 -3
  8. package/skills/agentforce-architecture-analyze/scripts/sf_cli.py +77 -10
  9. package/skills/agentforce-architecture-analyze/scripts/tests/test_end_to_end_fixture.py +1 -0
  10. package/skills/agentforce-architecture-analyze/scripts/tests/test_flow_children_inflation.py +1 -0
  11. package/skills/agentforce-architecture-analyze/scripts/tests/test_main_pipeline.py +53 -2
  12. package/skills/agentforce-architecture-analyze/scripts/tests/test_resolve_creds.py +184 -36
  13. package/skills/agentforce-architecture-analyze/scripts/tests/test_rest_client.py +17 -0
  14. package/skills/agentforce-architecture-analyze/scripts/tests/test_sf_cli.py +165 -11
  15. package/skills/agentforce-architecture-analyze/scripts/tests/test_skill_md_pipeline_block.py +319 -0
  16. package/skills/agentforce-bot-upgrade/SKILL.md +3 -1
  17. package/skills/agentforce-d360-analyze/SKILL.md +28 -10
  18. package/skills/agentforce-d360-analyze/scripts/dc.py +200 -50
  19. package/skills/agentforce-d360-analyze/scripts/discover_sessions.py +10 -6
  20. package/skills/agentforce-d360-analyze/scripts/fetch_dc.py +22 -6
  21. package/skills/agentforce-d360-analyze/scripts/resolve_session.py +21 -13
  22. package/skills/agentforce-d360-analyze/scripts/tests/test_dc_and_resolve_session.py +298 -76
  23. package/skills/agentforce-d360-analyze/scripts/tests/test_default_target_org.py +432 -0
  24. package/skills/agentforce-d360-analyze/scripts/tests/test_discover_sessions.py +1 -1
  25. package/skills/agentforce-d360-analyze/scripts/tests/test_resolve_session_main.py +9 -3
  26. package/skills/agentforce-d360-analyze/scripts/tests/test_skill_md_prefix_block.py +176 -0
  27. package/skills/agentforce-generate/SKILL.md +21 -1
  28. package/skills/agentforce-generate/references/known-issues.md +51 -1
  29. package/skills/agentforce-generate/references/legacy-nga-regression-eval.md +547 -0
  30. package/skills/agentforce-generate/references/upgrade-legacy-agent-to-agentscript.md +577 -0
  31. package/skills/agentforce-generate/scripts/upgrade-legacy-nga-analyze.py +404 -0
  32. package/skills/agentforce-generate/scripts/upgrade-legacy-nga-run-trials.sh +58 -0
  33. package/skills/agentforce-persona-generate/SKILL.md +505 -0
  34. package/skills/agentforce-persona-generate/assets/checklist-template.md +100 -0
  35. package/skills/agentforce-persona-generate/assets/persona-encoding-template.md +252 -0
  36. package/skills/agentforce-persona-generate/assets/persona-template.md +229 -0
  37. package/skills/agentforce-persona-generate/assets/sample-dialog-template.md +50 -0
  38. package/skills/agentforce-persona-generate/assets/workshop-outline-template.md +97 -0
  39. package/skills/agentforce-persona-generate/examples/concierge-persona.md +189 -0
  40. package/skills/agentforce-persona-generate/examples/concierge-sample-dialog.md +70 -0
  41. package/skills/agentforce-persona-generate/examples/drover-persona.md +194 -0
  42. package/skills/agentforce-persona-generate/examples/drover-sample-dialog.md +62 -0
  43. package/skills/agentforce-persona-generate/examples/steady-hand-persona.md +188 -0
  44. package/skills/agentforce-persona-generate/examples/steady-hand-sample-dialog.md +68 -0
  45. package/skills/agentforce-persona-generate/examples/yt-persona.md +195 -0
  46. package/skills/agentforce-persona-generate/examples/yt-sample-dialog.md +66 -0
  47. package/skills/agentforce-persona-generate/references/attributions.md +36 -0
  48. package/skills/agentforce-persona-generate/references/interaction-design-notes.md +30 -0
  49. package/skills/agentforce-persona-generate/references/persona-encoding-guide.md +566 -0
  50. package/skills/agentforce-persona-generate/references/persona-framework.md +796 -0
  51. package/skills/agentforce-persona-generate/references/refinement-mappings.md +31 -0
  52. package/skills/agentforce-persona-generate/references/scoring-rubric.md +58 -0
  53. package/skills/agentforce-persona-generate/references/voice-catalog.json +2327 -0
  54. package/skills/agentforce-persona-generate/references/workshop-question-policy.md +90 -0
  55. package/skills/agentforce-persona-generate/references/workshop-scenario-seeds.md +119 -0
  56. package/skills/agentforce-persona-generate/scripts/parse_agent_yaml.py +223 -0
  57. package/skills/consumer-goods-accruals-datakit-deploy/SKILL.md +17 -27
  58. package/skills/consumer-goods-accruals-datakit-deploy/scripts/setup.js +7 -17
  59. package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/00-check-prerequisites.js +47 -63
  60. package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/01-download-static-resource.js +10 -13
  61. package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/02-replace-org-id.js +46 -46
  62. package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/03-deploy-metadata.js +4 -21
  63. package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/06-create-dataspace.js +58 -82
  64. package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/07-deploy-accruals-reports.js +16 -315
  65. package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/08-deploy-ui.js +9 -24
  66. package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/09-completion.js +44 -44
  67. package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/utils.js +11 -63
  68. package/skills/consumer-goods-rtr-datacloud-export-configure/SKILL.md +2 -1
  69. package/skills/consumer-goods-tpe-dashboard-configure/SKILL.md +2 -1
  70. package/skills/consumer-goods-tpe-dashboard-custom-kpi-configure/SKILL.md +2 -1
  71. package/skills/consumer-goods-tpe-datakit-deploy/SKILL.md +2 -1
  72. package/skills/data360-schema-get/SKILL.md +3 -3
  73. package/skills/design-systems-slds-validate/references/report-format.md +1 -1
  74. package/skills/dx-app-analytics-query/SKILL.md +8 -8
  75. package/skills/dx-org-manage/SKILL.md +1 -0
  76. package/skills/dx-org-shape-manage/SKILL.md +1 -0
  77. package/skills/dx-org-snapshot-manage/SKILL.md +172 -0
  78. package/skills/dx-org-snapshot-manage/examples/create_error_output.json +16 -0
  79. package/skills/dx-org-snapshot-manage/examples/create_success_output.json +19 -0
  80. package/skills/dx-org-snapshot-manage/examples/delete_output.json +9 -0
  81. package/skills/dx-org-snapshot-manage/examples/get_output.json +19 -0
  82. package/skills/dx-org-snapshot-manage/examples/list_output.json +36 -0
  83. package/skills/dx-org-snapshot-manage/references/cli_flags.md +179 -0
  84. package/skills/dx-org-snapshot-manage/references/snapshot_usage.md +55 -0
  85. package/skills/dx-org-trial-expiration-check/SKILL.md +1 -1
  86. package/skills/dx-org-trial-expiration-check/scripts/check_expiration.sh +2 -2
  87. package/skills/education-cloud-student-recruitment-agent-configure/SKILL.md +7 -5
  88. package/skills/education-cloud-student-recruitment-agent-configure/references/prerequisites.md +11 -11
  89. package/skills/experience-content-media-image-generate/SKILL.md +83 -0
  90. package/skills/experience-content-media-image-generate/scripts/download-image.sh +84 -0
  91. package/skills/experience-ui-bundle-app-coordinate/SKILL.md +12 -12
  92. package/skills/experience-ui-bundle-app-coordinate/references/phase-completion-validation.md +3 -3
  93. package/skills/experience-ui-bundle-app-coordinate/references/phase-execution-pattern.md +9 -7
  94. package/skills/experience-ui-bundle-app-coordinate/scripts/check-dangling-refs.mjs +132 -0
  95. package/skills/experience-ui-bundle-app-coordinate/scripts/check-hosting-target.mjs +62 -0
  96. package/skills/experience-ui-bundle-app-coordinate/scripts/check-phase-1-complete.mjs +71 -0
  97. package/skills/experience-ui-bundle-app-coordinate/scripts/check-phase-4-complete.mjs +95 -0
  98. package/skills/experience-ui-bundle-app-coordinate/scripts/check-phase-6-ready.mjs +78 -0
  99. package/skills/experience-ui-bundle-app-coordinate/scripts/check-prerequisites.mjs +21 -0
  100. package/skills/experience-ui-bundle-app-coordinate/scripts/check-sfdx-project.mjs +28 -0
  101. package/skills/experience-ui-bundle-custom-app-generate/SKILL.md +3 -1
  102. package/skills/experience-ui-bundle-custom-app-generate/scripts/resolve-uibundle-path.mjs +40 -0
  103. package/skills/experience-ui-bundle-frontend-generate/SKILL.md +7 -5
  104. package/skills/experience-ui-bundle-frontend-generate/scripts/check-preconditions.mjs +70 -0
  105. package/skills/experience-ui-bundle-frontend-generate/scripts/resolve-ui-bundle.mjs +76 -0
  106. package/skills/experience-ui-bundle-frontend-generate/scripts/verify-rules.mjs +115 -0
  107. package/skills/experience-ui-bundle-metadata-generate/SKILL.md +7 -3
  108. package/skills/experience-ui-bundle-metadata-generate/references/angular-metadata-generate.md +1 -1
  109. package/skills/experience-ui-bundle-metadata-generate/references/react-metadata-generate.md +1 -1
  110. package/skills/experience-ui-bundle-metadata-generate/scripts/check-api-version.mjs +43 -0
  111. package/skills/experience-ui-bundle-metadata-generate/scripts/detect-framework.mjs +131 -0
  112. package/skills/experience-ui-bundle-metadata-generate/scripts/verify-bundle-location.mjs +152 -0
  113. package/skills/experience-ui-bundle-mfa-configure/references/branding.md +10 -6
  114. package/skills/external-diagram-mermaid-generate/SKILL.md +12 -12
  115. package/skills/field-service-data-capture-migrate/references/component-mapping.md +1 -1
  116. package/skills/field-service-data-capture-migrate/references/fsm-dc-capability-catalog.md +1 -2
  117. package/skills/field-service-data-capture-migrate/references/known-deploy-errors.md +1 -0
  118. package/skills/field-service-data-capture-migrate/references/transformer-rules.md +1 -1
  119. package/skills/field-service-data-capture-migrate/scripts/transform_flow.py +12 -1
  120. package/skills/field-service-data-capture-migrate/scripts/vendor/build_flow.py +4 -1
  121. package/skills/field-service-setup-orchestrator-get/SKILL.md +0 -1
  122. package/skills/insurance-brokerage-agency-billing-configure/SKILL.md +233 -0
  123. package/skills/insurance-brokerage-agency-billing-configure/references/accounting-setup.md +117 -0
  124. package/skills/insurance-brokerage-agency-billing-configure/references/billing-rules-config.md +237 -0
  125. package/skills/insurance-brokerage-agency-billing-configure/references/billing-settings.md +271 -0
  126. package/skills/insurance-brokerage-agency-billing-configure/references/demo-policy-config.md +138 -0
  127. package/skills/insurance-brokerage-agency-billing-configure/references/org-defaults.md +64 -0
  128. package/skills/insurance-brokerage-agency-billing-configure/references/permissions-config.md +226 -0
  129. package/skills/insurance-brokerage-agency-billing-configure/references/prerequisites.md +142 -0
  130. package/skills/life-sciences-fieldsalesrep-coordinate/SKILL.md +3 -2
  131. package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-5-visit-creation-execution-state-and-recovery.md +3 -3
  132. package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-5-visit-creation-overview.md +68 -45
  133. package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-5-visit-creation-visit-creation-data.md +17 -18
  134. package/skills/life-sciences-kam-coordinate/references/stage-5-data-and-plan-templates-overview.md +16 -3
  135. package/skills/life-sciences-kam-coordinate/references/stage-5-data-creation-data.md +16 -13
  136. package/skills/marketing-message-test/SKILL.md +194 -0
  137. package/skills/marketing-message-test/references/api-contract.md +333 -0
  138. package/skills/omnistudio-callable-apex-generate/SKILL.md +3 -3
  139. package/skills/omnistudio-datamapper-generate/SKILL.md +6 -6
  140. package/skills/omnistudio-datapacks-deploy/SKILL.md +11 -11
  141. package/skills/omnistudio-dependencies-analyze/SKILL.md +5 -5
  142. package/skills/omnistudio-epc-catalog-generate/SKILL.md +6 -6
  143. package/skills/omnistudio-flexcard-generate/SKILL.md +6 -6
  144. package/skills/omnistudio-integration-procedure-generate/SKILL.md +6 -6
  145. package/skills/omnistudio-omniscript-generate/SKILL.md +6 -5
  146. package/skills/platform-apex-logs-debug/SKILL.md +1 -0
  147. package/skills/platform-metadata-deploy/SKILL.md +1 -0
  148. package/skills/platform-models-api-configure/SKILL.md +5 -5
  149. package/skills/platform-soql-query/SKILL.md +1 -0
  150. package/skills/service-itsm-agentic-setup-cmdb-coordinate/SKILL.md +17 -6
  151. package/skills/service-itsm-agentic-setup-incident-sla-configure/SKILL.md +107 -192
  152. package/skills/service-itsm-agentic-setup-incident-sla-configure/assets/attach-milestone-action.json +6 -6
  153. package/skills/service-itsm-agentic-setup-incident-sla-configure/examples/milestone-patterns.md +49 -20
  154. package/skills/service-itsm-agentic-setup-incident-sla-configure/examples/output-templates.md +4 -4
  155. package/skills/service-itsm-agentic-setup-incident-sla-configure/references/mcp-invocation.md +224 -290
  156. package/skills/service-itsm-agentic-setup-incident-sla-configure/references/workflow.md +295 -0
  157. package/skills/service-itsm-incident-priority-configure/SKILL.md +1 -1
  158. package/skills/service-itsm-slack-itservice-configure/SKILL.md +2 -1
  159. package/skills/service-itsm-slack-itservice-configure/references/manage-slack-connection.md +2 -2
  160. package/skills/service-omni-channel-setup-coordinate/SKILL.md +20 -13
  161. package/skills/service-omni-channel-setup-coordinate/scripts/integration-driver.sh +5 -55
  162. package/skills/service-omni-channel-setup-coordinate/scripts/tests/test_omni_contracts.py +0 -38
  163. package/skills/service-omni-command-center-analyze/SKILL.md +2 -3
  164. package/skills/service-omni-command-center-analyze/scripts/analyze.sh +3 -3
  165. package/skills/tableau-next-asset-create/README.md +65 -0
  166. package/skills/tableau-next-asset-create/SKILL.md +409 -0
  167. package/skills/tableau-next-asset-create/references/admin-users.md +149 -0
  168. package/skills/tableau-next-asset-create/references/ai-readiness.md +355 -0
  169. package/skills/tableau-next-asset-create/references/alerts.md +111 -0
  170. package/skills/tableau-next-asset-create/references/build-workflow.md +819 -0
  171. package/skills/tableau-next-asset-create/references/dashboard-authoring.md +302 -0
  172. package/skills/tableau-next-asset-create/references/dashboard-design-principles.md +352 -0
  173. package/skills/tableau-next-asset-create/references/data-transform-gotchas.md +210 -0
  174. package/skills/tableau-next-asset-create/references/data-understanding.md +387 -0
  175. package/skills/tableau-next-asset-create/references/deep-reference-index.md +74 -0
  176. package/skills/tableau-next-asset-create/references/destructive-operations.md +62 -0
  177. package/skills/tableau-next-asset-create/references/edit-dashboard.md +273 -0
  178. package/skills/tableau-next-asset-create/references/edit-visualization.md +529 -0
  179. package/skills/tableau-next-asset-create/references/empty-source-handling.md +104 -0
  180. package/skills/tableau-next-asset-create/references/ingest-and-metric-gotchas.md +638 -0
  181. package/skills/tableau-next-asset-create/references/insight-bundle.md +69 -0
  182. package/skills/tableau-next-asset-create/references/large-flat-file-handling.md +331 -0
  183. package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/_envelope.json +54 -0
  184. package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/_shared-widget-fields.json +122 -0
  185. package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/add_page.json +29 -0
  186. package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/delete_page.json +27 -0
  187. package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/discard_dashboard.json +11 -0
  188. package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/move_widget.json +30 -0
  189. package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/move_widget_to_page.json +30 -0
  190. package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/place_widget_on_page.json +30 -0
  191. package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/remove_widget_from_dashboard.json +16 -0
  192. package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/remove_widget_from_page.json +26 -0
  193. package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/rename_page.json +28 -0
  194. package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/save_dashboard.json +18 -0
  195. package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/undo.json +11 -0
  196. package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/upsert_button_widget.json +69 -0
  197. package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/upsert_container_widget.json +88 -0
  198. package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/upsert_filter_widget.json +146 -0
  199. package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/upsert_metric_widget.json +78 -0
  200. package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/upsert_navigation_widget.json +80 -0
  201. package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/upsert_parameter_widget.json +160 -0
  202. package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/upsert_text_widget.json +103 -0
  203. package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/upsert_visualization_widget.json +68 -0
  204. package/skills/tableau-next-asset-create/references/sdm-tool-reference.md +721 -0
  205. package/skills/tableau-next-asset-create/references/semantic-query-and-enrichment.md +355 -0
  206. package/skills/tableau-next-asset-create/references/shared-gates.md +322 -0
  207. package/skills/tableau-next-asset-create/references/sharing-and-promotion.md +306 -0
  208. package/skills/tableau-next-asset-create/references/tasks/ai-readiness-audit.md +51 -0
  209. package/skills/tableau-next-asset-create/references/tasks/analyze-data.md +48 -0
  210. package/skills/tableau-next-asset-create/references/tasks/build-dashboard.md +66 -0
  211. package/skills/tableau-next-asset-create/references/tasks/build-end-to-end.md +73 -0
  212. package/skills/tableau-next-asset-create/references/tasks/create-data-transform.md +51 -0
  213. package/skills/tableau-next-asset-create/references/tasks/create-viz.md +58 -0
  214. package/skills/tableau-next-asset-create/references/tasks/edit-dashboard.md +80 -0
  215. package/skills/tableau-next-asset-create/references/tasks/edit-sdm.md +106 -0
  216. package/skills/tableau-next-asset-create/references/tasks/edit-viz.md +40 -0
  217. package/skills/tableau-next-asset-create/references/tasks/enrich-model.md +68 -0
  218. package/skills/tableau-next-asset-create/references/tasks/ingest-flat-file.md +68 -0
  219. package/skills/tableau-next-asset-create/references/tasks/manage-alert.md +35 -0
  220. package/skills/tableau-next-asset-create/references/tasks/profile-dataset.md +47 -0
  221. package/skills/tableau-next-asset-create/references/tasks/promote-or-reuse.md +46 -0
  222. package/skills/tableau-next-asset-create/references/tasks/provision-user.md +39 -0
  223. package/skills/tableau-next-asset-create/references/tasks/query-model.md +92 -0
  224. package/skills/tableau-next-asset-create/references/tasks/review-verified-questions.md +42 -0
  225. package/skills/tableau-next-asset-create/references/tasks/share-asset.md +37 -0
  226. package/skills/tableau-next-asset-create/references/verified-questions.md +125 -0
  227. package/skills/tableau-next-asset-create/references/viz-authoring.md +992 -0
  228. package/skills/experience-ui-bundle-app-coordinate/scripts/check-dangling-refs.sh +0 -42
  229. package/skills/experience-ui-bundle-app-coordinate/scripts/check-hosting-target.sh +0 -26
  230. package/skills/experience-ui-bundle-app-coordinate/scripts/check-phase-1-complete.sh +0 -35
  231. package/skills/experience-ui-bundle-app-coordinate/scripts/check-phase-4-complete.sh +0 -47
  232. package/skills/experience-ui-bundle-app-coordinate/scripts/check-phase-6-ready.sh +0 -33
  233. package/skills/experience-ui-bundle-app-coordinate/scripts/check-prerequisites.sh +0 -20
  234. package/skills/experience-ui-bundle-app-coordinate/scripts/check-sfdx-project.sh +0 -15
  235. package/skills/experience-ui-bundle-custom-app-generate/scripts/resolve-uibundle-path.sh +0 -30
  236. package/skills/experience-ui-bundle-frontend-generate/scripts/check-preconditions.sh +0 -37
  237. package/skills/experience-ui-bundle-frontend-generate/scripts/resolve-ui-bundle.sh +0 -66
  238. package/skills/experience-ui-bundle-frontend-generate/scripts/verify-rules.sh +0 -58
  239. package/skills/experience-ui-bundle-metadata-generate/scripts/check-api-version.sh +0 -30
  240. package/skills/experience-ui-bundle-metadata-generate/scripts/detect-framework.sh +0 -73
  241. package/skills/experience-ui-bundle-metadata-generate/scripts/verify-bundle-location.sh +0 -118
  242. package/skills/service-itsm-agentic-setup-incident-sla-configure/assets/predefined-incident-policy.json +0 -102
@@ -9,7 +9,7 @@ exposes four meta-tools:
9
9
  - `mcp__headless-360__dispatch({url, method, body?, query_params?})` — POST / PATCH / DELETE HTTP
10
10
 
11
11
  **Dispatch takes raw HTTP**, not `{operation_id, arguments}`. Give it the full `url`
12
- (`/services/data/v67.0/...`), `method`, optional `body`, and optional `query_params` — the server
12
+ (`/services/data/v{version}/...`), `method`, optional `body`, and optional `query_params` — the server
13
13
  signs the request with the JWT bound to the current MCP session and forwards it to the org. The
14
14
  skill never handles credentials or an org alias — everything is derived from the session.
15
15
 
@@ -26,7 +26,6 @@ skill never handles credentials or an org alias — everything is derived from t
26
26
  - [Create SLA Policy (SlaProcess)](#create-sla-policy-slaprocess)
27
27
  - [Attach Milestone](#attach-milestone)
28
28
  - [Milestone Actions (Phase 2.5 — Warn / Escalate)](#milestone-actions-phase-25--warn--escalate)
29
- - [Create Entitlement (standard sObject)](#create-entitlement-standard-sobject)
30
29
  - [Predefined Incident Policy (Phase 0.6 detect + Phase 2-OOB seed)](#predefined-incident-policy-phase-06-detect--phase-2-oob-seed)
31
30
  - [Verify SLA engagement](#verify-sla-engagement)
32
31
  - [Gotchas](#gotchas)
@@ -49,183 +48,149 @@ this skill uses none.)
49
48
 
50
49
  | Method + path | Purpose |
51
50
  |---------------|---------|
52
- | `GET /services/data/v67.0/connect/setup/discovery/feature/service-cloud-itsm-manage-sla-policies/status` | Phase 0.5 — read the SLA Management for IT Service feature status |
53
- | `POST /services/data/v67.0/connect/setup/discovery/feature/service-cloud-itsm-manage-sla-policies/enable` | Phase 0.5 — enable the feature (flips Simplified SLA Setup) |
54
- | `GET /services/data/v67.0/tooling/query` | Phase 0.5 — read SLA Versioning (`EntitlementSettings.IsEntitlementVersioningEnabled`) via `query_params.q` |
55
- | `PATCH /services/data/v67.0/tooling/sobjects/EntitlementSettings/000000000000000AAA` | Phase 0.5 — turn on SLA Versioning if off |
56
- | `GET /services/data/v67.0/sobjects/Incident/describe` | Preflight — Incident Management on + SLA fields present |
57
- | `GET /services/data/v67.0/query` | SOQL reads (BusinessHours, SlaProcess, EntityMilestone) via `query_params.q` |
58
- | `GET /services/data/v67.0/connect/sla-management/sla-policies` | Phase 0.6 — detect the OOB "Standard Support for Incidents" policy via `query_params.processTypes=Incident` |
59
- | `POST /services/data/v67.0/connect/sla-management/milestone-types` | Create MilestoneType |
60
- | `POST /services/data/v67.0/connect/sla-management/sla-policies` | Create SLA Policy (SlaProcess) |
61
- | `POST /services/data/v67.0/connect/sla-management/sla-policies/<slaId>/milestones` | Attach Milestone |
62
- | `POST /services/data/v67.0/sobjects/Entitlement` | Create Entitlement (standard sObject) |
63
- | `POST /services/data/v67.0/connect/sla-management/entitlement-criteria` | Phase 2-OOB — `describe` first, then attempt the OOB always-match criterion (`Subject NotEqual <sentinel>`); if the create still `400`s after using the described schema, fall back to a date-windowed Entitlement (the route works — a wrong-payload `400`, not a platform gap) |
64
- | `POST /services/data/v67.0/sobjects/Incident` | Create a test Incident |
65
- | `POST /services/data/v67.0/sobjects/BusinessHours` | Phase 2.5 — create an IST (or other-timezone) BusinessHours for the policy/Entitlement (createable; **not** API-deletable) |
66
- | `POST /services/data/v67.0/connect/sla-management/sla-policies/<slaId>/milestones/<milestoneId>/actions` | Phase 2.5 — attach a Warn/Escalate milestone action (delegate via the `create-milestone-action` op) |
67
-
68
- Minimum API version is **67.0** — `headless-360` currently only routes `v67.0+`.
51
+ | `GET /headless/invoke/platform/slasettings/get-sla-management-permission` | Phase 0.5 — read whether SLA Management is on (composite: Entitlements + Simplified SLA Setup + Pause Milestone). Delegated to `itsm-shakti/SLASettings` |
52
+ | `PATCH /headless/invoke/platform/slasettings/set-sla-management-permission` | Phase 0.5 — turn SLA Management on (`isEnabled:true`; flips the three prefs atomically; requires Entitlements already on or it throws). **Reversible.** Delegated to `itsm-shakti/SLASettings` |
53
+ | `GET /headless/invoke/platform/slasettings/get-sla-versioning-permission` | Phase 0.5 — read whether SLA Versioning is on. Delegated to `itsm-shakti/SLASettings` |
54
+ | `PATCH /headless/invoke/platform/slasettings/set-sla-versioning-permission` | Phase 0.5 — turn SLA Versioning on (`isEnabled:true`). **Separate write; permanent / one-way** — the controller refuses to disable it. Delegated to `itsm-shakti/SLASettings` |
55
+ | `GET /services/data/v{version}/sobjects/Incident/describe` | Preflight — Incident Management on + SLA fields present |
56
+ | `GET /services/data/v{version}/query` | SOQL reads (BusinessHours, SlaProcess, EntityMilestone) via `query_params.q` |
57
+ | `GET /headless/invoke/platform/slasettings` | Phase 0.6 / 2-OOB — the seeder's existence map (get-existing-checkbox-states); lowercase keys `{incident,problem,changeRequest}`, `true` = default already seeded (dedup read) |
58
+ | `PATCH /headless/invoke/platform/slasettings/save-selected-options` | Phase 2-OOB — seed the predefined bundle in one call; body `{"selectedOptions":["incident"]}` (**lowercase** — capitalized 500s); provisions the full active policy + Entitlement + criteria |
59
+ | `GET /services/data/v{version}/connect/sla-management/sla-policies` | List Incident SLA policies via `query_params.processTypes=Incident` (coexistence detect — is another active Incident policy present?) |
60
+ | `POST /services/data/v{version}/connect/sla-management/milestone-types` | Create MilestoneType |
61
+ | `POST /services/data/v{version}/connect/sla-management/sla-policies` | Create SLA Policy (SlaProcess) |
62
+ | `POST /services/data/v{version}/connect/sla-management/sla-policies/<slaId>/milestones` | Attach Milestone |
63
+ | `PATCH /services/data/v{version}/connect/sla-management/sla-policies/<slaId>/status?isActive=true&createEntitlement=true` | **Custom flow** — activate the policy + auto-provision its Entitlement (`isActive`/`createEntitlement` are QUERY params) |
64
+ | `POST /services/data/v{version}/connect/sla-management/entitlement-criteria` | **Custom flow** — auto-apply the activated policy's Entitlement to matching records (delegated to `csp-sun/create-entitlement-criteria`); `describe` first and send its exact fields (rejects `filterType`). OOB does not use this — the seeder provisions its own criteria |
65
+ | `POST /services/data/v{version}/sobjects/Incident` | Create a test Incident |
66
+ | `POST /services/data/v{version}/sobjects/BusinessHours` | Phase 2.5 — create an IST (or other-timezone) BusinessHours for the policy/Entitlement (createable; **not** API-deletable) |
67
+ | `POST /services/data/v{version}/connect/sla-management/sla-policies/<slaId>/milestones/<milestoneId>/actions` | Phase 2.5 — attach a Warn/Escalate milestone action (delegate via the `create-milestone-action` op) |
68
+
69
+ **API VERSION:** the `v{version}` segment in every URL above (and everywhere in this
70
+ skill) is resolved to the target org's own current API version at dispatch — resolve it
71
+ once via `GET /services/data/` at the start of the run and substitute it everywhere; do
72
+ NOT pin a release-specific version (e.g. `v67.0`), and do NOT mix versions within a run.
73
+ Minimum API version is **67.0** — `headless-360` currently only routes `v67.0+`, so the
74
+ org-resolved version is always at or above that floor.
69
75
 
70
76
  ---
71
77
 
72
78
  ## Phase 0.5 — SLA Management for IT Service prerequisite gate
73
79
 
74
- "SLA Management for IT Service" is a Salesforce Go Setup Discovery feature — verified apiName
75
- `service-cloud-itsm-manage-sla-policies`. **Do not guess other apiNames for this** — every other
76
- guess returns `400 NOT_FOUND`; this exact string is the correct one. If it ever needs re-confirming
77
- for a different org/release, the list-all route `GET /services/data/v67.0/connect/setup/discovery/features`
78
- returns every feature's apiName + status in one call.
79
-
80
- **"SLA Management for IT Service" is a Setup Discovery composite of two sub-steps — Simplified SLA
81
- Setup AND SLA Versioning — and reads as enabled/Complete only when BOTH are on.** In Setup it shows
82
- **In Progress** while either is off.
83
-
84
- **One enable call turns on both — they are inseparable.** The feature's enablement automation (the
85
- platform recipe `turnOnSLAManagementForITService`) runs two hardcoded, non-optional steps: (1) turns
86
- on Entitlements (`IsEntitlementsEnabled`) + Simplified SLA Setup + Pause Milestone; (2) turns on **SLA
87
- Versioning** (`EntitlementSettings.IsEntitlementVersioningEnabled`, a one-way DB migration). So the
88
- single feature `enable` call below **auto-enables SLA Versioning as a side effect** — no separate
89
- versioning write is required, and there is **no supported way to enable Simplified SLA Setup while
90
- leaving versioning off** (both steps are inseparable at the platform level). `IsEntitlementVersioningEnabled`
91
- is a Tooling singleton (fixed Id `000000000000000AAA`, keyPrefix `0HE`, one row per org).
92
-
93
- **SLA Versioning is permanent / one-way.** Salesforce rejects any attempt to turn it back off
94
- ("Versioning cannot be disabled once it is enabled"), even if SLA Management is later disabled.
95
-
96
- Because the enable is inseparable and versioning is irreversible, **never enable without explicit,
97
- informed consent for the permanent switch** — an explicit permanence-gated `AskUserQuestion`, kept
98
- separate from the master-enable ack (see *Ack structure* below). If the user declines, enable **nothing** (enabling the feature would flip versioning
99
- anyway), SLA Management stays incomplete, and the run **halts**.
100
-
101
- This is the root of W-23979084: the skill enabled the feature on a request that also said "don't
102
- enable versioning," versioning turned on anyway (a side effect of the enable), and the skill then
103
- **falsely reported it as off**. The fix: get permanence consent up front, and after the write re-read
80
+ **SLA Management for IT Service reads as fully enabled only when BOTH sub-settings are on —
81
+ Simplified SLA Setup AND SLA Versioning.** In Setup it shows **In Progress** while either is off. Both
82
+ the reads and the writes below are **delegated to `itsm-shakti/SLASettings`** (which owns the
83
+ SLA-Management settings surface) — `discover` → `describe` → `dispatch` its
84
+ operations rather than re-deriving the routes here. The paths below are the delegate's, shown for
85
+ orientation; take the authoritative request/response shape from its `describe`.
86
+
87
+ **Two independent switches, two separate writes — enabling SLA Management does NOT auto-enable
88
+ Versioning.**
89
+ - **SLA Management** (`set-sla-management-permission`, `isEnabled:true`) flips its composite prefs
90
+ atomically (Simplified SLA Setup + Pause Milestone + the Entitlements pref). It **requires
91
+ Entitlements already on** or the controller throws. This toggle is **reversible** (`isEnabled:false`).
92
+ - **SLA Versioning** (`set-sla-versioning-permission`, `isEnabled:true`) is a **separate** write and a
93
+ **permanent, one-way** migration. Turning SLA Management back off does **not** turn Versioning back
94
+ off — the controller refuses any disable ("SLA Versioning cannot be disabled once it is enabled").
95
+ So completing the gate takes **both** writes, and the versioning write is irreversible.
96
+
97
+ Because the versioning write is irreversible, **never fire it without explicit, informed consent for
98
+ the permanent switch** — an explicit permanence-gated `AskUserQuestion`, kept separate from the
99
+ master-enable ack (see *Ack structure* below). If the user declines the permanence, do **not** complete
100
+ the gate (SLA Management alone does not satisfy it), and the run **halts**.
101
+
102
+ This is the root of the versioning false-report defect: the skill turned Versioning on but then
103
+ **falsely reported it as off**. The fix: get permanence consent up front, and after each write re-read
104
104
  and report the **real** state.
105
105
 
106
- ### Read — feature status
106
+ ### Read — SLA Management state
107
107
 
108
108
  ```json
109
109
  mcp__headless-360__dispatch_readonly({
110
- "url": "/services/data/v67.0/connect/setup/discovery/feature/service-cloud-itsm-manage-sla-policies/status",
110
+ "url": "/headless/invoke/platform/slasettings/get-sla-management-permission",
111
111
  "method": "GET"
112
112
  })
113
+ → true | false // composite over Entitlements + Simplified SLA Setup + Pause Milestone
113
114
  ```
114
115
 
115
- ```json
116
- {
117
- "apiName": "service-cloud-itsm-manage-sla-policies",
118
- "status": "NOT_ENABLED",
119
- "enableBlockedReasons": [],
120
- "disableBlockedReasons": [],
121
- "blockedByApexLock": false,
122
- "dependencyStatuses": []
123
- }
124
- ```
116
+ - `true` → SLA Management is on; now read SLA Versioning below. The gate passes only if **both** reads return `true`.
117
+ - `false` → ack with the user (per *Ack structure*), confirm Entitlements are on, then write `set-sla-management-permission`.
125
118
 
126
- - `status == "ENABLED"` → **Simplified SLA Setup** is on — now read SLA Versioning below. SLA
127
- Management is fully enabled (the gate) only if **both** this is `ENABLED` **and** versioning is `true`.
128
- - `status == "NOT_ENABLED"` with non-empty `enableBlockedReasons` → **stop**, relay the reasons, do
129
- not attempt to enable.
130
- - `status == "NOT_ENABLED"` with empty `enableBlockedReasons` → ack with the user (per *Ack structure*), then enable.
131
-
132
- ### Read — SLA Versioning
119
+ ### Read — SLA Versioning state
133
120
 
134
121
  ```json
135
122
  mcp__headless-360__dispatch_readonly({
136
- "url": "/services/data/v67.0/tooling/query",
137
- "method": "GET",
138
- "query_params": { "q": "SELECT IsEntitlementVersioningEnabled FROM EntitlementSettings" }
123
+ "url": "/headless/invoke/platform/slasettings/get-sla-versioning-permission",
124
+ "method": "GET"
139
125
  })
126
+ → true | false
140
127
  ```
141
128
 
142
- ```json
143
- {
144
- "size": 1, "totalSize": 1, "done": true,
145
- "records": [{ "IsEntitlementVersioningEnabled": true }]
146
- }
147
- ```
129
+ `true` is **permanent** — never attempt to flip it back. Surface the permanence to the user before the write; never enable it silently.
148
130
 
149
- **SLA Versioning is a one-way switch.** Once `IsEntitlementVersioningEnabled` is `true`, Salesforce
150
- does not support flipping it back — even if SLA Management is later turned off. Always surface this
151
- to the user before enabling it — never enable silently.
152
-
153
- ### Enable — feature (only after explicit user confirmation)
131
+ ### Enable — SLA Management (only after the master/feature ack; skip if the read returned `true`)
154
132
 
155
133
  ```json
156
134
  mcp__headless-360__dispatch({
157
- "url": "/services/data/v67.0/connect/setup/discovery/feature/service-cloud-itsm-manage-sla-policies/enable",
158
- "method": "POST",
159
- "body": {}
135
+ "url": "/headless/invoke/platform/slasettings/set-sla-management-permission",
136
+ "method": "PATCH",
137
+ "body": { "isEnabled": true }
160
138
  })
161
- → 201 { "success": true }
162
139
  ```
163
140
 
164
- **This single call enables the whole composite — Simplified SLA Setup *and*, as a side effect, the
165
- permanent SLA Versioning.** Do not trust `success: true` alone — re-run the status GET above and
166
- require `"status": "ENABLED"`, **and** re-run the SLA Versioning query and require
167
- `IsEntitlementVersioningEnabled: true`, before moving on.
141
+ Requires Entitlements already on (else it throws); reversible. Do **not** trust the write response —
142
+ re-read `get-sla-management-permission` and require `true` before the versioning write.
168
143
 
169
- ### Enable — SLA Versioning (fallback only — normally unnecessary)
170
-
171
- The feature enable above already turns versioning on, so you should **not** need a separate versioning
172
- write. Use this Tooling PATCH **only** if the post-enable re-read shows versioning still `false` (e.g.
173
- an older org whose enable automation predates the versioning step). It, too, requires explicit consent
174
- for the permanent switch — versioning is irreversible either way.
144
+ ### Enable — SLA Versioning (a SEPARATE write; only after the distinct permanence ack; skip if the read returned `true`)
175
145
 
176
146
  ```json
177
147
  mcp__headless-360__dispatch({
178
- "url": "/services/data/v67.0/tooling/sobjects/EntitlementSettings/000000000000000AAA",
148
+ "url": "/headless/invoke/platform/slasettings/set-sla-versioning-permission",
179
149
  "method": "PATCH",
180
- "body": {
181
- "FullName": "EntitlementSettings",
182
- "Metadata": { "enableEntitlementVersioning": true }
183
- }
150
+ "body": { "isEnabled": true }
184
151
  })
185
- → 204 No Content (empty body)
186
152
  ```
187
153
 
188
- `FullName` is mandatory — the PATCH is rejected without it. The PATCH response body is empty on
189
- success — **re-run the Tooling query above and require `IsEntitlementVersioningEnabled: true`**
190
- before moving on (never trust a write response alone).
154
+ **Permanent / one-way** — no disable path exists (the controller refuses `isEnabled:false` afterward).
155
+ Re-read `get-sla-versioning-permission` and require `true` before moving on (never trust the write
156
+ response alone).
191
157
 
192
158
  ### Ack structure — two separate consent questions
193
159
 
194
- Enabling the feature is **one inseparable action with a permanent consequence**: it turns on the SLA
195
- Management feature **and, as a one-way side effect, permanently enables SLA Versioning**. **Only SLA
196
- Versioning is permanent.** Scope the reversibility precisely so the customer is neither over- nor
197
- under-warned:
160
+ Completing the gate takes two writes with very different stakes — a **reversible** SLA Management
161
+ enable and an **irreversible** SLA Versioning enable. Scope the reversibility precisely so the
162
+ customer is neither over- nor under-warned:
198
163
 
199
164
  - **Master Incident Management pref** — fully reversible; enabling it has no permanent side effect.
200
- - **SLA Management for IT Service feature** — the feature toggle can be turned off again later, **but
201
- turning it off does NOT turn SLA Versioning back off**. Versioning stays on permanently once the
202
- enable flips it. So do **not** describe the feature as cleanly "reversible" without this caveat — a
203
- customer could otherwise assume disabling SLA Management undoes versioning, which is false.
204
- - **SLA Versioning** — permanent / one-way; guarded against disable at the platform level.
205
-
206
- **Ask two separate `AskUserQuestion`s — never merge them into one.** The master enable and the
207
- permanent-versioning consent carry very different stakes (reversible prerequisite vs. irreversible
208
- consequence); bundling them forces an all-or-nothing accept and conflates the two. Do **not** offer a
209
- "versioning-off" path (none exists). Build each from the reads, not a fixed script.
210
-
211
- - If **both** the feature and versioning are already on → skip the acks; the gate passes.
165
+ - **SLA Management for IT Service** (`set-sla-management-permission`) — **reversible**; can be turned
166
+ off again later. Turning it off does **not** turn SLA Versioning back off.
167
+ - **SLA Versioning** (`set-sla-versioning-permission`) — a **separate** write; permanent / one-way,
168
+ guarded against disable at the platform level.
169
+
170
+ **Ask two separate `AskUserQuestion`s — never merge them into one.** The reversible enables and the
171
+ permanent-versioning consent carry very different stakes; bundling them forces an all-or-nothing
172
+ accept and conflates the two. Do **not** offer a "versioning-off" path (none exists). Build each from
173
+ the reads, not a fixed script.
174
+
175
+ - If **both** SLA Management and Versioning are already on → skip the acks; the gate passes.
212
176
  - **Q1 — master prerequisite (only if master Incident Mgmt is `NOT_ENABLED`):** ask to enable it
213
177
  first. It's **reversible** — present it as a prerequisite with **no** permanence warning. Offer
214
178
  **Enable** or **Stop — make no changes**. A declined master → HALT.
215
- - **Q2 — permanence ack for the feature (a distinct question, after the master is on):** if the
216
- feature is off (and `enableBlockedReasons` is empty) → ask, in customer terms: enabling **SLA
217
- Management for IT Service** also turns on **SLA Versioning**, which **can't be turned off once
218
- enabled** — the SLA Management feature itself can be turned off again later, but that will **not**
219
- turn Versioning back off; Versioning is permanent. Offer **Enable** or **Stop — make no changes**.
220
- - **Any decline — including a request to enable Simplified SLA Setup but *not* versioning — means
221
- HALT.** There is no way to honor "Simplified without versioning" (enabling the feature flips
222
- versioning anyway); enable **nothing** and do not proceed to SLA/milestone setup. Say plainly why —
223
- they're inseparable and versioning is permanent.
224
- - **Never** enable silently or bury the permanent switch in a default — a bare or repeated "enable
225
- SLA" is not consent for the permanent SLA Versioning switch. This is the W-23979084 bug.
226
- - **After enabling, re-read both** and report the real, both-on state — never trust the write
227
- response. The gate passes only when Simplified SLA Setup is `ENABLED` **and**
228
- `IsEntitlementVersioningEnabled` is `true`.
179
+ - **Q2 — enable + permanence ack (a distinct question, after the master is on):** if SLA Management
180
+ and/or Versioning are off → ask, in customer terms: completing SLA Management setup turns on **SLA
181
+ Management** and, as a separate step, **SLA Versioning**, which **can't be turned off once enabled**
182
+ — SLA Management itself can be turned off again later, but that will **not** turn Versioning back
183
+ off; Versioning is permanent. Offer **Enable** or **Stop — make no changes**.
184
+ - **Any decline — including a request to enable SLA Management but *not* Versioning — means HALT.**
185
+ The gate needs Versioning on, and there is no way to honor "SLA Management without Versioning" as a
186
+ completed gate; enable **no further** writes and do not proceed to SLA/milestone setup (a reversible
187
+ SLA Management enable already made may stand). Say plainly why — Versioning is required and permanent.
188
+ - **Never** enable Versioning silently or bury the permanent switch in a default — a bare or repeated
189
+ "enable SLA" is not consent for the permanent SLA Versioning switch. This is the versioning
190
+ false-report bug.
191
+ - **After each write, re-read** and report the real, both-on state — never trust the write response.
192
+ The gate passes only when `get-sla-management-permission` **and** `get-sla-versioning-permission`
193
+ both return `true`.
229
194
 
230
195
  ---
231
196
 
@@ -266,7 +231,7 @@ Setup Discovery instead.
266
231
 
267
232
  ```json
268
233
  mcp__headless-360__dispatch_readonly({
269
- "url": "/services/data/v67.0/connect/setup/discovery/features",
234
+ "url": "/services/data/v{version}/connect/setup/discovery/features",
270
235
  "method": "GET"
271
236
  })
272
237
  ```
@@ -300,7 +265,7 @@ The endpoint returns the full feature catalog (~763 entries, ~1.1 MB) and does n
300
265
 
301
266
  ```json
302
267
  mcp__headless-360__dispatch_readonly({
303
- "url": "/services/data/v67.0/sobjects/Incident/describe",
268
+ "url": "/services/data/v{version}/sobjects/Incident/describe",
304
269
  "method": "GET"
305
270
  })
306
271
  ```
@@ -320,7 +285,7 @@ than reading the whole body — you only need to confirm those three field names
320
285
 
321
286
  ```json
322
287
  mcp__headless-360__dispatch_readonly({
323
- "url": "/services/data/v67.0/query",
288
+ "url": "/services/data/v{version}/query",
324
289
  "method": "GET",
325
290
  "query_params": { "q": "SELECT Id, Name FROM BusinessHours WHERE IsActive = true AND IsDefault = true" }
326
291
  })
@@ -335,7 +300,7 @@ If `body.records` is empty, stop — the user must create default Business Hours
335
300
 
336
301
  ```json
337
302
  mcp__headless-360__dispatch({
338
- "url": "/services/data/v67.0/connect/sla-management/milestone-types",
303
+ "url": "/services/data/v{version}/connect/sla-management/milestone-types",
339
304
  "method": "POST",
340
305
  "body": {
341
306
  "name": "Incident First Response",
@@ -354,7 +319,7 @@ absent, the create failed — surface `body`.
354
319
 
355
320
  ```json
356
321
  mcp__headless-360__dispatch({
357
- "url": "/services/data/v67.0/connect/sla-management/sla-policies",
322
+ "url": "/services/data/v{version}/connect/sla-management/sla-policies",
358
323
  "method": "POST",
359
324
  "body": {
360
325
  "name": "Incident SLA Policy",
@@ -363,7 +328,7 @@ mcp__headless-360__dispatch({
363
328
  "businessHourId": "<BusinessHoursId>",
364
329
  "createdDateEntryCriteria": true,
365
330
  "closedExitCriteria": true,
366
- "active": true,
331
+ "active": false,
367
332
  "versionDefault": true
368
333
  }
369
334
  })
@@ -374,12 +339,33 @@ verify state via SOQL:
374
339
 
375
340
  ```json
376
341
  mcp__headless-360__dispatch_readonly({
377
- "url": "/services/data/v67.0/query",
342
+ "url": "/services/data/v{version}/query",
378
343
  "method": "GET",
379
344
  "query_params": { "q": "SELECT Id, Name, SobjectType, IsActive, BusinessHoursId FROM SlaProcess WHERE Id = '<slaId>'" }
380
345
  })
381
346
  ```
382
347
 
348
+ **Custom flow creates the policy inactive** (`active: false`) — activation is a separate, explicit
349
+ step so the Entitlement is **auto-provisioned**. After the milestones are attached, activate via the
350
+ `csp-sun/activate-sla-policy` leaf:
351
+
352
+ ```json
353
+ mcp__headless-360__dispatch({
354
+ "url": "/services/data/v{version}/connect/sla-management/sla-policies/<slaId>/status",
355
+ "method": "PATCH",
356
+ "query_params": { "isActive": "true", "createEntitlement": "true" }
357
+ })
358
+ ```
359
+
360
+ `isActive` and `createEntitlement` are **QUERY params, not a body** (sending them in a body `500`s
361
+ headless). `createEntitlement=true` **auto-provisions the Entitlement** and returns its
362
+ `entitlementId` — bind the auto-apply criteria to it (see *Entitlement Criteria* / the
363
+ `csp-sun/create-entitlement-criteria` leaf). Verify by reading the policy back (`IsActive = true`)
364
+ via SOQL, never the write response. **This is the custom-flow activation path — a `200` with a
365
+ returned `entitlementId` is the success shape.** The **OOB/predefined seed path does NOT use this PATCH
366
+ at all** — its single `save-selected-options` call seeds an already-active policy and auto-provisions
367
+ the Entitlement itself (see *Predefined Incident Policy*).
368
+
383
369
  ---
384
370
 
385
371
  ## Attach Milestone
@@ -389,7 +375,7 @@ mcp__headless-360__dispatch_readonly({
389
375
 
390
376
  ```json
391
377
  mcp__headless-360__dispatch({
392
- "url": "/services/data/v67.0/connect/sla-management/sla-policies/<slaId>/milestones",
378
+ "url": "/services/data/v{version}/connect/sla-management/sla-policies/<slaId>/milestones",
393
379
  "method": "POST",
394
380
  "body": {
395
381
  "milestoneTypeId": "<MilestoneTypeId>",
@@ -411,9 +397,9 @@ mcp__headless-360__dispatch({
411
397
  })
412
398
  ```
413
399
 
414
- **`startTimeBasedOn`** controls when the timer starts. Send **`"MILESTONE_CRITERIA"`** (matches OOB and every default pattern) to start the clock when the milestone's ACTIVE criteria first match. It is a free string with two recognized values — **`MILESTONE_CRITERIA`** (criteria-based / dynamic start) and **`SLA_PROCESS`** (the fallback); any other value silently defaults to the `SLA_PROCESS` behavior (no error). The fallback anchors the timer to the **Incident's `SlaStartDate`** (→ its `CreatedDate` if `SlaStartDate` is null) — **not** the SLA-process record's created date. **This choice is not runtime-verifiable in the standard verify flow:** for a test Incident that matches the SLA at creation, both settings compute the same `TargetDate` (≈ `SlaStartDate + timeTrigger`) — they diverge only when the criteria first match *after* creation (e.g. a later field change), which the Phase 3 test does not exercise. So send the OOB value and rely on it; there is no Phase-3 assertion that distinguishes the two (unlike the ACTIVE criterion, whose effect **is** observable via tiering — see below). `milestoneCriteria` is mandatory. `milestoneAgreementType` is mandatory per the UI and lives **inside each `milestoneCriteria[]` item** (it maps to the `MilestoneCriteria.MilestoneAgreementType` sub-entity field — sending it at the top level of the milestone body returns `JSON_PARSER_ERROR: Unrecognized field`). Valid UI values are **`SLA`** (customer-facing agreement) or **`OLA`** (internal / operational). The API accepts any string because the underlying field is plain `Text(40)` with no server-side picklist enforcement — an unrecognized value persists to the DB but the UI treats it as blank; omitting the field entirely also succeeds silently but leaves the record's Milestone Agreement Type null (W-23959162). Success: `body.id` is the new Milestone Id.
400
+ **`startTimeBasedOn`** controls when the timer starts. Send **`"MILESTONE_CRITERIA"`** (matches OOB and every default pattern) to start the clock when the milestone's ACTIVE criteria first match. It is a free string with two recognized values — **`MILESTONE_CRITERIA`** (criteria-based / dynamic start) and **`SLA_PROCESS`** (the fallback); any other value silently defaults to the `SLA_PROCESS` behavior (no error). The fallback anchors the timer to the **Incident's `SlaStartDate`** (→ its `CreatedDate` if `SlaStartDate` is null) — **not** the SLA-process record's created date. **This choice is not runtime-verifiable in the standard verify flow:** for a test Incident that matches the SLA at creation, both settings compute the same `TargetDate` (≈ `SlaStartDate + timeTrigger`) — they diverge only when the criteria first match *after* creation (e.g. a later field change), which the Phase 3 test does not exercise. So send the OOB value and rely on it; there is no Phase-3 assertion that distinguishes the two (unlike the ACTIVE criterion, whose effect **is** observable via tiering — see below). `milestoneCriteria` is mandatory. `milestoneAgreementType` is mandatory per the UI and lives **inside each `milestoneCriteria[]` item** (it maps to the `MilestoneCriteria.MilestoneAgreementType` sub-entity field — sending it at the top level of the milestone body returns `JSON_PARSER_ERROR: Unrecognized field`). Valid UI values are **`SLA`** (customer-facing agreement) or **`OLA`** (internal / operational). The API accepts any string because the underlying field is plain `Text(40)` with no server-side picklist enforcement — an unrecognized value persists to the DB but the UI treats it as blank; omitting the field entirely also succeeds silently but leaves the record's Milestone Agreement Type null. Success: `body.id` is the new Milestone Id.
415
401
 
416
- **`milestoneState` MUST be UPPERCASE and comes from a fixed set — this is load-bearing.** Valid values are **`ACTIVE`**, **`COMPLETE`**, **`PAUSE`**, **`UNPAUSE`** (there is **no `CANCEL`** state). `MilestoneService` compares `milestoneState` against `"ACTIVE"` with a **case-sensitive** `String.equals`, so `"Active"`/`"active"` (or any wrong case) **silently fails to register the ACTIVE criterion** — the create still returns `201 success:true`, but the priority/entry filter is never written and the Setup UI shows blank Activation Criteria. The milestone loses its Priority gate, so **in practice every Incident engages the lowest-`order` milestone of that MilestoneType regardless of its Priority** — a priority-tiered policy collapses to one tier. Use `ACTIVE` for the engagement (Priority) criterion and `COMPLETE` for the completion (Status) criterion; never send `CANCEL` (once the `ACTIVE` Priority criterion is correct it gates engagement, making a cancel criterion redundant).
402
+ **`milestoneState` MUST be UPPERCASE and comes from a fixed set — this is load-bearing.** Valid values are **`ACTIVE`**, **`COMPLETE`**, **`PAUSE`**, **`UNPAUSE`** (there is **no `CANCEL`** state). The server compares `milestoneState` against `"ACTIVE"` **case-sensitively**, so `"Active"`/`"active"` (or any wrong case) **silently fails to register the ACTIVE criterion** — the create still returns `201 success:true`, but the priority/entry filter is never written and the Setup UI shows blank Activation Criteria. The milestone loses its Priority gate, so **in practice every Incident engages the lowest-`order` milestone of that MilestoneType regardless of its Priority** — a priority-tiered policy collapses to one tier. Use `ACTIVE` for the engagement (Priority) criterion and `COMPLETE` for the completion (Status) criterion; never send `CANCEL` (once the `ACTIVE` Priority criterion is correct it gates engagement, making a cancel criterion redundant).
417
403
 
418
404
  **The create response NEVER echoes `milestoneCriteria` — it always returns `milestoneCriteria: []` even on success** (the create handler only sets `id`/`success`; only a subsequent GET/read-back populates criteria). So the `201` proves nothing about whether criteria persisted. **Verify by runtime, not the response:** after seeding, create a **non-matching-tier** test Incident (e.g. a Moderate/Low one for a Critical-first policy) and confirm its `EntityMilestone.TargetResponseInMins` matches that tier's `timeTrigger`, not order-1's. A Critical-only test can't catch a dropped criterion because Critical maps to order-1, which is also the collapse fallback.
419
405
 
@@ -444,7 +430,7 @@ mcp__headless-360__describe(id="<create-milestone-action operation id>")
444
430
  ```
445
431
 
446
432
  Then `dispatch` the `POST` it returns:
447
- `/services/data/v67.0/connect/sla-management/sla-policies/<slaId>/milestones/<milestoneId>/actions`.
433
+ `/services/data/v{version}/connect/sla-management/sla-policies/<slaId>/milestones/<milestoneId>/actions`.
448
434
 
449
435
  ### Checkpoint roles (the `checkpoint` block)
450
436
 
@@ -474,16 +460,20 @@ offsetBeforeTarget = round( milestoneTargetMinutes × (1 − X/100) )
474
460
 
475
461
  "Escalate **on breach**" → a Violation with `timeLength: 0`.
476
462
 
477
- ### Proven bodies (live-validated, Field Update)
463
+ ### Milestone-action bodies (Field Update; example shapes, pending live verification)
478
464
 
479
465
  **Default action is a Field Update** — self-contained, no org dependencies. `actionFlow` returns an
480
466
  opaque `201 / success:false / INTERNAL_SERVER_ERROR` on empty-flow auto-create in some orgs — avoid it
481
- as the default; Email Alert needs a pre-built template. Warning (warn at 75% of a 2-hr milestone → 30
482
- min before):
467
+ as the default; Email Alert needs a pre-built template. **`Incident.Priority` is derived from
468
+ Impact × Urgency and is NOT directly updateable** (`createable:false / updateable:false` — see *Verify
469
+ SLA engagement*), so a Field Update targeting `Priority` fails `INVALID_FIELD_FOR_INSERT_UPDATE`.
470
+ Escalate by driving Priority's **updateable inputs** instead: raise `Urgency` on the warning and
471
+ `Impact` on the breach — both axes High drives the derived Priority to its top tier. Warning (warn at
472
+ 75% of a 2-hr milestone → 30 min before):
483
473
 
484
474
  ```json
485
475
  mcp__headless-360__dispatch({
486
- "url": "/services/data/v67.0/connect/sla-management/sla-policies/<slaId>/milestones/<milestoneId>/actions",
476
+ "url": "/services/data/v{version}/connect/sla-management/sla-policies/<slaId>/milestones/<milestoneId>/actions",
487
477
  "method": "POST",
488
478
  "body": {
489
479
  "isSuccessCheckpoint": false,
@@ -491,16 +481,17 @@ mcp__headless-360__dispatch({
491
481
  "entityName": "Incident",
492
482
  "actionFieldUpdate": {
493
483
  "name": "SLA Warn 75pct RES", "sourceTable": "Incident", "targetTable": "Incident",
494
- "columnEnumOrId": "Priority", "developerName": "SLA_Warn_75_RES",
484
+ "columnEnumOrId": "Urgency", "developerName": "SLA_Warn_75_RES",
495
485
  "operationString": "LITERAL", "literal": "High"
496
486
  }
497
487
  }
498
488
  })
499
489
  ```
500
490
 
501
- Violation (escalate on breach → `Priority = Critical`): same shape with
491
+ Violation (escalate on breach → raise `Impact = High`): same shape with
502
492
  `checkpoint: { "isWarning": false, "timeLength": 0, "timeUnit": "Minutes" }`, `name`
503
- `"SLA Escalate on Breach RES"`, `developerName` `SLA_Escalate_Breach_RES`, `literal` `"Critical"`.
493
+ `"SLA Escalate on Breach RES"`, `developerName` `SLA_Escalate_Breach_RES`, `columnEnumOrId` `"Impact"`,
494
+ `literal` `"High"`.
504
495
 
505
496
  **Make `name`/`developerName` unique per milestone.** A `WorkflowFieldUpdate` `DeveloperName` is unique
506
497
  on the Incident object, so reusing `SLA_Warn_75` on a second milestone fails with
@@ -548,179 +539,122 @@ shift the milestone clock. State this plainly instead of implying IST changed th
548
539
 
549
540
  ---
550
541
 
551
- ## Create Entitlement (standard sObject)
552
-
553
- Entitlement is NOT part of the `/connect/sla-management/` surface — create it via the sObject
554
- endpoint.
555
-
556
- ```json
557
- mcp__headless-360__dispatch({
558
- "url": "/services/data/v67.0/sobjects/Entitlement",
559
- "method": "POST",
560
- "body": {
561
- "Name": "Incident SLA Entitlement",
562
- "AccountId": "<AccountId>",
563
- "SlaProcessId": "<slaId>",
564
- "BusinessHoursId": "<BusinessHoursId>",
565
- "StartDate": "<YYYY-MM-DD>",
566
- "EndDate": "<YYYY-MM-DD + 1 year>"
567
- }
568
- })
569
- ```
570
-
571
- `Entitlement.Status` is date-computed: `StartDate` in the future → `Inactive`; `StartDate` ≤ today
572
- AND `EndDate` ≥ today → `Active`. For immediate SLA engagement, backdate `StartDate` to yesterday.
573
- Success: `body.id`.
574
-
575
- ---
576
-
577
542
  ## Predefined Incident Policy (Phase 0.6 detect + Phase 2-OOB seed)
578
543
 
579
544
  The out-of-box **"Standard Support for Incidents"** policy is what Salesforce seeds from Setup's
580
- "Create Predefined Policies" step (Incident process type only). That step is **Aura-only** — the
581
- checkbox calls `DefaultSlaPolicyController.saveSelectedOptions`, an `@AuraEnabled` controller whose
582
- only caller of `DefaultSlaService.createDefaultSlaPolicies` is that Aura action; there is **no public
583
- REST/Connect wrapper**, so the headless MCP cannot invoke the seeder directly. But the seeder just
584
- reads core's `default-sla-policies/incident.json` and writes it through the **same backend** as the
585
- public `/connect/sla-management/*` routes above — so the skill replicates that resource's exact
586
- output with routes it already uses. The full template (policy flags, 2 milestone types, **6
587
- milestones**, entitlement criterion) lives in **`assets/predefined-incident-policy.json`** — load
588
- and follow it; the values below are the shape.
545
+ "Create Predefined Policies" step (Incident process type only). That seeder — the SLA Settings page's
546
+ **Create Predefined Policies** action (`save-selected-options`) — is served headless on the **Aura dispatcher route**
547
+ `/headless/invoke/platform/slasettings/*`, so the skill invokes the **real seeder in ONE call** rather
548
+ than replicating its output. The seeder builds the entire **active** bundle itself — policy + 2
549
+ MilestoneTypes + 6 milestones (Critical/High per-tier, Moderate+Low merged) + Entitlement + auto-apply
550
+ criteria — the same core out-of-box seed data, with Core's own Priority/Status handling. (Route
551
+ live-proven for both read and write; the former hand-rebuilt replica over `/connect/sla-management/*`
552
+ plus the manual `POST /sobjects/Entitlement` is retired.)
589
553
 
590
554
  ### Detect first (no server idempotency → mandatory)
591
555
 
592
556
  Re-seeding is **not** idempotent — a second seed duplicates every artifact. Before offering to seed,
593
- read the existing Incident policies and name-match:
557
+ read the seeder's own existence map:
594
558
 
595
559
  ```json
596
560
  mcp__headless-360__dispatch_readonly({
597
- "url": "/services/data/v67.0/connect/sla-management/sla-policies",
598
- "method": "GET",
599
- "query_params": { "processTypes": "Incident" }
561
+ "url": "/headless/invoke/platform/slasettings",
562
+ "method": "GET"
563
+ })
564
+ ```
565
+
566
+ It returns a **lowercase-keyed** map, e.g. `{"incident": true}` (keys: `incident`, `problem`,
567
+ `changeRequest`; a key is `true` when that type's default is already seeded). If `incident` is `true`,
568
+ the OOB policy is already present — report it and do **not** re-seed. (Fallback: SOQL `SELECT Id, Name
569
+ FROM SlaProcess WHERE SobjectType = 'Incident' AND Name = 'Standard Support for Incidents'`.)
570
+
571
+ ### Seed (only if not already present)
572
+
573
+ One call:
574
+
575
+ ```json
576
+ mcp__headless-360__dispatch({
577
+ "url": "/headless/invoke/platform/slasettings/save-selected-options",
578
+ "method": "PATCH",
579
+ "body": { "selectedOptions": ["incident"] }
600
580
  })
601
581
  ```
602
582
 
603
- If any returned policy's name is **"Standard Support for Incidents"**, it is already seeded — report
604
- it and do **not** re-seed. (Fallback: SOQL `SELECT Id, Name FROM SlaProcess WHERE SobjectType =
605
- 'Incident' AND Name = 'Standard Support for Incidents'`.)
606
-
607
- ### Seed recipe (only if not already present)
608
-
609
- Uses the Phase 2 routes above, in this order:
610
-
611
- 1. **Resolve the 2 MilestoneTypes — detect first, create only what is missing.** Enabling the SLA
612
- Management feature pre-seeds a default MilestoneType catalog (commonly `First Response`,
613
- `Follow Up`, `Periodic Update`, **`Resolve Within`**), so a blind `POST .../milestone-types` for a
614
- name that already exists returns **HTTP 500 ("already exists")** and leaves the policy half-seeded.
615
- First read the catalog — SOQL `SELECT Id, Name FROM MilestoneType WHERE Name IN ('Acknowledge
616
- Within', 'Resolve Within')` (or `GET .../milestone-types`) — **reuse any match by id**, and `POST
617
- .../milestone-types` (`recurrenceType: OneTime`) **only** for the name(s) not already present.
618
- Capture both ids (whether reused or created) **for chaining only — when you narrate the reuse,
619
- name the type ("reusing the existing First Response type"); never append its queried Id, masked or
620
- full (Output contract).**
621
- 2. Create the SLA Policy `Standard Support for Incidents` (`POST .../sla-policies`) with
622
- `processType: "Incident"`, `businessHourId` = default, `createdDateEntryCriteria: true`,
623
- `closedExitCriteria: true`, `versionDefault: true`, **`active: true`** (create it active directly —
624
- do **not** use the Connect activate PATCH, which can 500 headless). Verify via SOQL on `SlaProcess`,
625
- then narrate the policy by that verified name — never the captured/queried Id (Output contract).
626
- 3. Attach the **6 milestones** (`POST .../sla-policies/<id>/milestones`, one per row). Reuse
627
- `assets/attach-milestone.json`. Send **`startTimeBasedOn: "MILESTONE_CRITERIA"`** on every
628
- milestone — the OOB timer starts when the milestone criteria first match; the public route reads
629
- this exact token (`MilestoneService` treats `MILESTONE_CRITERIA` as the criteria-based/dynamic
630
- start; its only other recognized value, `SLA_PROCESS`, anchors to the Incident's `SlaStartDate`).
631
- Validate each Priority/Status value against the live `Incident` picklist first. For the **mid
632
- tier**, map to the org's actual mid-priority label — `Moderate` on the standard ITSM picklist, but
633
- many orgs label it `Medium` — inside the merged orders 5–6 `Priority` OR rows (keep the `Low` row).
634
- Drop a row from the OR **only** when its value is genuinely absent from the picklist, and note any
635
- dropped or relabeled tier in the report.
636
-
637
- | order | milestoneType | timeTrigger | active criterion (Priority) | completion (Status) |
638
- |-------|---------------|-------------|-----------------------------|---------------------|
639
- | 1 | Acknowledge Within | 30 | `Equals Critical` | `NotEqual New` |
640
- | 2 | Resolve Within | 120 | `Equals Critical` | `In [Resolved, Completed, Closed]` |
641
- | 3 | Acknowledge Within | 60 | `Equals High` | `NotEqual New` |
642
- | 4 | Resolve Within | 240 | `Equals High` | `In [Resolved, Completed, Closed]` |
643
- | 5 | Acknowledge Within | 240 | `Equals Moderate` OR `Equals Low` (`filterLogic: "1 OR 2"`) | `NotEqual New` |
644
- | 6 | Resolve Within | 960 | `Equals Moderate` OR `Equals Low` (`filterLogic: "1 OR 2"`) | `In [Resolved, Completed, Closed]` |
645
-
646
- This mirrors core's `default-sla-policies/incident.json` shape: Critical and High are per-tier;
647
- **Moderate and Low are one merged tier** (ACTIVE `filterLogic "1 OR 2"` over two Priority Equals rows).
648
-
649
- The **active** criterion is the one the public Attach-Milestone `milestoneCriteria` carries
650
- (`milestoneState: ACTIVE`, `milestoneAgreementType: SLA`, `filterType: RuleFilter`) — seeding it
651
- **is what tiers the policy**: it gates which Incidents engage each milestone. Because all three tiers
652
- reuse the same two MilestoneTypes, if the ACTIVE criterion fails to persist (e.g. a wrong-case
653
- `milestoneState` — see the case-sensitivity warning above), the milestone loses its Priority gate and
654
- in practice every Incident engages the lowest-`order` milestone (Critical, 30/120) regardless of Priority. Each milestone also carries a
655
- completion criterion (`milestoneState: COMPLETE`, `Status In …`). **The core template's per-tier
656
- CANCEL criterion is intentionally dropped** — the public route has no `CANCEL` state, and once the
657
- ACTIVE Priority criterion is correct it already prevents off-tier engagement, so a cancel criterion is
658
- redundant. **Verify tiering by runtime** (see the case-sensitivity warning): seed, then create a
659
- **Moderate/Low** test Incident and confirm its `EntityMilestone` lands on the 240/960 tier, not 30/120.
660
-
661
- **Priority OR is expressed via `filterLogic`, not an `In` operator.** `filterItems` AND by default and
662
- there is no `In` operator, but the merged Moderate-or-Low tier's ACTIVE criterion uses
663
- `filterLogic: "1 OR 2"` across two `Priority Equals` rows — the same `customLogicExpression` the
664
- public milestone-criteria route consumes, so no separate per-value milestone is needed. If the live
665
- route rejects `filterLogic`, fall back to two separate `Priority Equals` milestones (Moderate, Low)
666
- with the same timeTriggers — behavior-equivalent. The `Status In` completion sets use the same
667
- `filterLogic: "1 OR 2 OR 3"` pattern (split into one row per value if the route rejects it).
668
-
669
- 4. Create the Entitlement (`POST /sobjects/Entitlement`) on the resolved Account, `SlaProcessId` =
670
- the seeded policy, backdated `StartDate`. **Attempt** the OOB always-match entitlement criterion
671
- (`Subject NotEqual <sentinel>`, see the asset) via `POST /connect/sla-management/entitlement-criteria`
672
- so the policy auto-matches every Incident like true OOB. **First `describe` that operation and send
673
- its exact input fields** — do **not** reuse the milestone-criteria body shape: `entitlement-criteria`
674
- rejects `filterType` (`400 JSON_PARSER_ERROR: Unrecognized field "filterType"`); its criterion body
675
- differs. If the create still fails after using the described schema, fall back to the date-windowed
676
- Entitlement alone and **disclose only the consequence, in plain customer terms**: the seeded policy
677
- then engages on Incidents wired to this Entitlement (`EntitlementId` set), not on every Incident
678
- automatically — to make it apply to all Incidents, add the always-match criterion via **Setup →
679
- Entitlement Management**. **Do NOT tell the user the route is "unreachable" or its schema
680
- "undiscoverable"** — that is inaccurate; the route works, the criterion body just needs its correct
681
- fields (a wrong-payload `400`, not a platform gap), and misattributing it reads as a bug. Never
682
- surface the raw sentinel string or a `JSON_PARSER_ERROR` in the customer report. The date-windowed
683
- Entitlement plus the milestone criteria are still enough to engage the Phase 3 test Incident.
684
- Narrate the Entitlement by name/Account, never its returned Id (Output contract).
685
- 5. Verify per **Verify SLA engagement** below with a **Moderate/Low** test Incident — its
686
- `EntityMilestone` must land on the 240/960 tier, not 30/120. Use a non-lowest tier: Critical is
687
- order-1, the collapse fallback, so it spawns a milestone even when the ACTIVE criterion was dropped
688
- and can't detect the bug. Then **STOP** — do not offer custom.
583
+ - **`selectedOptions` values MUST be lowercase** (`incident` / `problem` / `changeRequest`), matching
584
+ the existence-map keys. The capitalized `Incident` form returns a server-side **`500`** — this is the
585
+ single most common failure; the describe metadata's `{Incident,Problem,ChangeRequest}` casing is
586
+ misleading, so send lowercase.
587
+ - Success is **HTTP `200` with body `true`**. The seeded policy is **active**, and its Entitlement and
588
+ auto-apply criteria are provisioned by the seeder — there is **no** manual `POST /sobjects/Entitlement`
589
+ and **no** Connect activate PATCH (so the 500 that path could throw never arises).
590
+
591
+ ### Verify
592
+
593
+ Re-read the existence map (`GET /headless/invoke/platform/slasettings`) and confirm `incident: true`,
594
+ then SOQL `SlaProcess` for **"Standard Support for Incidents"** with `IsActive = true` (do not trust the
595
+ write body). Then verify runtime engagement per **Verify SLA engagement** below with a **Moderate/Low**
596
+ test Incident — its `EntityMilestone` must land on the 240/960 tier, not 30/120 (Critical is order-1,
597
+ the collapse fallback, so it can't detect a mis-tiered seed). Then **STOP** — do not offer custom.
598
+ Narrate the policy by name, never its Id (Output contract).
689
599
 
690
600
  ---
691
601
 
692
602
  ## Verify SLA engagement
693
603
 
694
- Create a test Incident:
604
+ Create a test Incident. **`Priority` is NOT directly writable on `Incident`** — the field is
605
+ `createable:false / updateable:false` (not a formula) and is **platform-derived from `Impact` ×
606
+ `Urgency`** via the ITSM priority matrix (both are `High | Medium | Low` picklists). Sending
607
+ `Priority` in the body fails with `INVALID_FIELD_FOR_INSERT_UPDATE`. So to land the test Incident on
608
+ a target tier, set **`Impact` and `Urgency`** (never `Priority`), then read the **derived** `Priority`
609
+ back to confirm which tier it resolved to — the matrix is **org-configurable**, so do NOT hardcode the
610
+ mapping. **Pick a tier that actually exercises the milestone under test — for a Priority-tiered or OOB
611
+ policy use a Moderate/Low Incident, NOT Critical.** Critical is the order-1 milestone (the collapse
612
+ fallback), so it always stamps an EntityMilestone and can't reveal a mis-tiered or dropped milestone
613
+ (the OOB Verify step mandates Moderate/Low for the same reason). (On the default matrix
614
+ `Impact=Medium, Urgency=Medium` → a mid tier and `Impact=High, Urgency=High` → `Critical`; treat these
615
+ as default-matrix illustrations, not guarantees — always read the derived `Priority` back.) Wire the
616
+ Entitlement explicitly (`EntitlementId`) so engagement is deterministic and does not depend on the
617
+ auto-apply criterion:
695
618
 
696
619
  ```json
697
620
  mcp__headless-360__dispatch({
698
- "url": "/services/data/v67.0/sobjects/Incident",
621
+ "url": "/services/data/v{version}/sobjects/Incident",
699
622
  "method": "POST",
700
- "body": { "Subject": "SLA test incident", "EntitlementId": "<EntitlementId>" }
623
+ "body": { "Subject": "SLA test incident", "Impact": "Medium", "Urgency": "Medium", "EntitlementId": "<EntitlementId>" }
701
624
  })
702
625
  ```
703
626
 
704
- Then confirm the Incident stamped an SLA start and an EntityMilestone:
627
+ Then confirm the derived Priority landed on the intended tier, and that the Incident stamped an SLA
628
+ start and an EntityMilestone:
705
629
 
706
630
  ```json
707
631
  mcp__headless-360__dispatch_readonly({
708
- "url": "/services/data/v67.0/query",
632
+ "url": "/services/data/v{version}/query",
709
633
  "method": "GET",
710
- "query_params": { "q": "SELECT Id, IncidentNumber, Subject, Status, SlaStartDate FROM Incident WHERE Id = '<incidentId>'" }
634
+ "query_params": { "q": "SELECT Id, IncidentNumber, Subject, Status, Priority, Impact, Urgency, SlaStartDate FROM Incident WHERE Id = '<incidentId>'" }
711
635
  })
712
636
  ```
713
637
 
714
638
  ```json
715
639
  mcp__headless-360__dispatch_readonly({
716
- "url": "/services/data/v67.0/query",
640
+ "url": "/services/data/v{version}/query",
717
641
  "method": "GET",
718
642
  "query_params": { "q": "SELECT Id, MilestoneType.Name, TargetDate, IsCompleted, IsViolated FROM EntityMilestone WHERE ParentEntityId = '<incidentId>'" }
719
643
  })
720
644
  ```
721
645
 
722
- `SlaStartDate` populated + at least one `EntityMilestone` row with a `TargetDate` = SLA engaged.
723
- `TargetDate` should equal `SlaStartDate + timeTrigger minutes` (business-hours-adjusted).
646
+ **At least one `EntityMilestone` row with a `TargetDate`** is the reliable proof the SLA engaged —
647
+ assert on that first. `Incident.SlaStartDate` is populated when the Incident is created with an
648
+ explicit `EntitlementId`, but can come back **null** when the Entitlement is applied hands-free by an
649
+ entitlement-criteria rule (the milestone still lands, with its `TargetDate` computed off `CreatedDate`
650
+ — the `SLA_PROCESS` fallback anchor). So treat a null `SlaStartDate` as a non-blocker, not a failure,
651
+ as long as the `EntityMilestone` is present on the correct tier.
652
+ When `SlaStartDate` is populated, `TargetDate` should equal `SlaStartDate + timeTrigger minutes`
653
+ (business-hours-adjusted), and
654
+ `EntityMilestone.TargetResponseInMins` should equal the target tier's `timeTrigger`. First confirm the
655
+ **derived** `Priority` on the Incident is the tier you intended (from the `Impact`/`Urgency` you set) —
656
+ if the org's matrix mapped your `Impact`/`Urgency` to a different Priority, adjust them and recreate
657
+ rather than reading the assertion against the wrong tier.
724
658
 
725
659
  ---
726
660
 
@@ -734,7 +668,7 @@ mcp__headless-360__dispatch_readonly({
734
668
  | SLA Policy create response is null | `POST /sla-policies` echoes most fields as `null` — always verify via SOQL on `SlaProcess`; then narrate the policy by the **verified name**, never the captured/queried Id (Output contract). |
735
669
  | Milestone filter payload | `milestoneCriteria` is mandatory (omitting it → `400: Criteria details cannot be empty`). Use `filterType: "RuleFilter"` with concrete `filterItems[]` — `filterType: "Formula"` triggers a 500. Operators are `Equals` (not `Equal`) and `NotEqual` (not `NotEquals`/`NotEqualTo`/`!=`); wrong forms → `POST_BODY_PARSE_ERROR: Invalid value for Filter Operation Enum`. |
736
670
  | `slaProcessId` rejected in body | The server returns `JSON_PARSER_ERROR: Unrecognized field "slaProcessId"` — the id is in the path only. |
737
- | Entitlement create + status | Create via `POST /sobjects/Entitlement` (standard sObject, not the Connect surface). Status is date-computed: a future `StartDate` → `Inactive`; backdate `StartDate` to yesterday for immediate SLA engagement in testing. |
738
- | OOB seed has no idempotency | `POST .../sla-policies` does not dedupe — re-seeding "Standard Support for Incidents" duplicates every artifact. Detect first via `GET .../sla-policies?processTypes=Incident` and name-match before seeding. |
739
- | Connect activate PATCH may 500 | The OOB backend flips the policy active via a Connect activate call; headless, that PATCH can 500. Create the SlaProcess with `active: true` directly instead (as the custom flow does). |
671
+ | OOB seed `selectedOptions` casing | The `save-selected-options` values MUST be **lowercase** (`incident`/`problem`/`changeRequest`), matching the existence-map keys. The capitalized `Incident` form returns a server-side **`500`** — the single most common OOB failure; the describe metadata's `{Incident,Problem,ChangeRequest}` casing is misleading. |
672
+ | OOB seed has no idempotency | `save-selected-options` does not dedupe — re-seeding "Standard Support for Incidents" duplicates every artifact. Detect first via `GET /headless/invoke/platform/slasettings` (existence map; `incident: true` = already seeded) before seeding. |
673
+ | OOB uses the seeder, not the Connect activate PATCH | The **OOB seed** does one `save-selected-options` call that seeds an already-active policy + auto-provisions its Entitlement — it never touches the Connect activate PATCH. The **custom flow** activates via the `csp-sun/activate-sla-policy` leaf (`isActive`+`createEntitlement` query params) — the no-500 activation path (a `200` with a returned `entitlementId` is the success shape). |
740
674
  | Never leak a record Id (SKILL.md Output contract) | In **every** user-facing message — interim narration *and* the final report, incl. "created milestone …" / "policy created …" / "reusing existing … →" progress lines — refer to the Phase-3 test Incident by its **`IncidentNumber`** (the verify SOQL selects it) and milestones/policy by their **name** — never the 15/18-char record Id (full **or masked**, e.g. `557VW…R3XVYA0`) or a `triggerId`. This covers **detected/reused** artifacts too — no `→ <Id>` "proof of reuse". Ids stay internal (chaining only). |