@salesforce/afv-skills 1.41.0 → 1.43.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 (288) hide show
  1. package/package.json +2 -6
  2. package/skills/automation-sandbox-post-copy-config-generate/SKILL.md +3 -0
  3. package/skills/automation-sandbox-post-copy-configure/SKILL.md +4 -0
  4. package/skills/design-systems-slds-validate/SKILL.md +2 -2
  5. package/skills/dx-app-analytics-query/SKILL.md +1 -3
  6. package/skills/dx-devops-conflict-resolve/SKILL.md +205 -0
  7. package/skills/dx-devops-conflict-resolve/examples/conflict-workflows.md +165 -0
  8. package/skills/dx-devops-conflict-resolve/references/deploy-failure-resolution.md +75 -0
  9. package/skills/dx-devops-conflict-resolve/references/git-conflict-resolution.md +124 -0
  10. package/skills/dx-devops-conflict-resolve/scripts/detect-conflicts.sh +91 -0
  11. package/skills/dx-devops-conflict-resolve/scripts/diagnose-deploy-failure.sh +156 -0
  12. package/skills/dx-devops-request-status/SKILL.md +160 -0
  13. package/skills/dx-devops-request-status/examples/polling-workflows.md +101 -0
  14. package/skills/dx-devops-request-status/references/cli-commands.md +176 -0
  15. package/skills/dx-devops-request-status/scripts/poll-status.sh +134 -0
  16. package/skills/dx-devops-test-failures-analyze/SKILL.md +6 -6
  17. package/skills/dx-devops-test-pipeline-configure/SKILL.md +7 -7
  18. package/skills/dx-devops-test-suite-assignments-configure/SKILL.md +6 -6
  19. package/skills/dx-devops-test-suite-run/SKILL.md +6 -6
  20. package/skills/dx-devops-work-item-manage/SKILL.md +2 -0
  21. package/skills/dx-org-manage/references/creating-scratch-org.md +5 -2
  22. package/skills/dx-org-manage/references/creating-snapshot.md +1 -0
  23. package/skills/dx-org-shape-manage/SKILL.md +152 -0
  24. package/skills/dx-org-shape-manage/examples/create_error_output.json +9 -0
  25. package/skills/dx-org-shape-manage/examples/create_success_output.json +9 -0
  26. package/skills/dx-org-shape-manage/examples/delete_output.json +11 -0
  27. package/skills/dx-org-shape-manage/examples/list_inactive_output.json +32 -0
  28. package/skills/dx-org-shape-manage/examples/list_output.json +24 -0
  29. package/skills/dx-org-shape-manage/references/cli_flags.md +135 -0
  30. package/skills/dx-org-switch/SKILL.md +2 -2
  31. package/skills/dx-org-trial-expiration-check/SKILL.md +2 -0
  32. package/skills/dx-pkg-post-install-configure/SKILL.md +3 -0
  33. package/skills/education-cloud-multi-campus-configure/SKILL.md +211 -0
  34. package/skills/education-cloud-multi-campus-configure/examples/hierarchy_visualization.md +174 -0
  35. package/skills/education-cloud-multi-campus-configure/examples/output_examples.md +54 -0
  36. package/skills/education-cloud-multi-campus-configure/examples/sample_hierarchy_input.csv +29 -0
  37. package/skills/education-cloud-multi-campus-configure/examples/sample_hierarchy_input_edgecases.csv +16 -0
  38. package/skills/education-cloud-multi-campus-configure/references/account_recordtype_prerequisite.md +44 -0
  39. package/skills/education-cloud-multi-campus-configure/references/delta_computation.md +33 -0
  40. package/skills/education-cloud-multi-campus-configure/references/error_handling.md +198 -0
  41. package/skills/education-cloud-multi-campus-configure/references/foundation_prerequisites.md +54 -0
  42. package/skills/education-cloud-multi-campus-configure/references/gotchas.md +16 -0
  43. package/skills/education-cloud-multi-campus-configure/references/hierarchy_parsing_rules.md +133 -0
  44. package/skills/education-cloud-multi-campus-configure/references/mcp-invocation.md +75 -0
  45. package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/SKILL.md +1 -1
  46. package/skills/experience-cms-brand-apply/SKILL.md +4 -1
  47. package/skills/experience-cms-brand-create/SKILL.md +197 -0
  48. package/skills/experience-cms-brand-create/assets/brand-template.json +329 -0
  49. package/skills/experience-cms-brand-create/references/brand-anatomy.md +120 -0
  50. package/skills/experience-cms-brand-create/references/disk-contract.md +84 -0
  51. package/skills/experience-cms-content-generate/SKILL.md +190 -0
  52. package/skills/experience-cms-content-generate/assets/display-formats.md +84 -0
  53. package/skills/experience-cms-content-generate/assets/payloads/create-content-bulk.json +11 -0
  54. package/skills/experience-cms-content-generate/assets/payloads/create-content-single.json +11 -0
  55. package/skills/experience-cms-content-generate/assets/payloads/publish-content.json +4 -0
  56. package/skills/experience-cms-content-generate/assets/payloads/update-content.json +9 -0
  57. package/skills/experience-cms-content-generate/assets/questions.md +241 -0
  58. package/skills/experience-cms-content-generate/examples/create-content-call.md +81 -0
  59. package/skills/experience-cms-content-generate/references/bulk-batching.md +56 -0
  60. package/skills/experience-cms-content-generate/references/content-type-classification.md +88 -0
  61. package/skills/experience-cms-content-generate/references/content-write-tool.md +95 -0
  62. package/skills/experience-cms-content-generate/references/delegation-protocol.md +37 -0
  63. package/skills/experience-cms-content-generate/references/edit-publish-workflow.md +63 -0
  64. package/skills/experience-cms-content-generate/references/error-recovery.md +72 -0
  65. package/skills/experience-cms-content-generate/references/identifier-resolution.md +26 -0
  66. package/skills/experience-cms-content-generate/references/intent-routing.md +45 -0
  67. package/skills/experience-cms-content-generate/references/principles.md +19 -0
  68. package/skills/experience-cms-content-generate/references/ux-rules.md +68 -0
  69. package/skills/experience-cms-content-generate/references/workspace-resolution.md +33 -0
  70. package/skills/experience-cms-content-type-generate/SKILL.md +449 -0
  71. package/skills/experience-cms-content-type-generate/assets/discovery-prompts.md +79 -0
  72. package/skills/experience-cms-content-type-generate/assets/schema-example.json +70 -0
  73. package/skills/experience-cms-content-type-generate/references/agent-checklist.md +50 -0
  74. package/skills/experience-cms-content-type-generate/references/anti-patterns.md +39 -0
  75. package/skills/experience-cms-content-type-generate/references/deployment-errors.md +27 -0
  76. package/skills/experience-cms-content-type-generate/references/discovery-details.md +106 -0
  77. package/skills/experience-cms-content-type-generate/references/discovery-query-rules.md +85 -0
  78. package/skills/experience-cms-content-type-generate/references/edit-fields-loop.md +48 -0
  79. package/skills/experience-cms-content-type-generate/references/pre-deploy-checklist.md +21 -0
  80. package/skills/experience-cms-content-type-generate/references/retrieve-and-reconcile.md +105 -0
  81. package/skills/experience-cms-content-type-generate/references/schema-rules.md +51 -0
  82. package/skills/experience-cms-content-type-generate/references/schema-summary-format.md +60 -0
  83. package/skills/experience-lds-graphql-generate/SKILL.md +4 -0
  84. package/skills/experience-lwc-accessibility-jest-run/SKILL.md +79 -0
  85. package/skills/experience-lwc-accessibility-jest-run/references/running-sa11y-jest-tests.md +205 -0
  86. package/skills/experience-lwc-design-generate/SKILL.md +5 -4
  87. package/skills/experience-lwc-generate/SKILL.md +10 -9
  88. package/skills/experience-ui-bundle-deploy/references/dev-preview.md +21 -0
  89. package/skills/experience-ui-bundle-deploy/references/social-login.md +1 -0
  90. package/skills/experience-ui-bundle-file-upload-generate/SKILL.md +6 -6
  91. package/skills/experience-ui-bundle-localize/SKILL.md +30 -37
  92. package/skills/experience-ui-bundle-localize/references/gotchas.md +23 -7
  93. package/skills/experience-ui-bundle-localize/references/i18n-setup.md +48 -4
  94. package/skills/experience-ui-bundle-localize/references/label-xml.md +22 -8
  95. package/skills/experience-ui-bundle-localize/references/verifying.md +39 -11
  96. package/skills/experience-ui-bundle-localize/scripts/detect-bundle-type.sh +118 -15
  97. package/skills/experience-ui-bundle-localize/scripts/tests/test-detect-bundle-type.sh +187 -0
  98. package/skills/experience-ui-bundle-mfa-configure/SKILL.md +13 -2
  99. package/skills/experience-ui-bundle-mfa-configure/references/social-login.md +1 -0
  100. package/skills/experience-ui-bundle-project-generate/SKILL.md +2 -2
  101. package/skills/integration-connectivity-generate/SKILL.md +11 -10
  102. package/skills/integration-eventing-cdc-configure/SKILL.md +6 -6
  103. package/skills/integration-eventing-subscription-configure/SKILL.md +6 -5
  104. package/skills/mobile-platform-native-capabilities-integrate/SKILL.md +2 -2
  105. package/skills/mobile-platform-offline-validate/scripts/package.json +1 -1
  106. package/skills/platform-agentexchange-partner-offers-configure/SKILL.md +8 -8
  107. package/skills/platform-custom-application-generate/SKILL.md +2 -0
  108. package/skills/platform-custom-field-generate/SKILL.md +8 -6
  109. package/skills/platform-custom-metadata-type-generate/SKILL.md +460 -0
  110. package/skills/platform-custom-metadata-type-generate/references/cmdt-records.md +251 -0
  111. package/skills/platform-custom-metadata-type-generate/scripts/sanitize-developer-name.sh +46 -0
  112. package/skills/platform-custom-setting-generate/SKILL.md +419 -0
  113. package/skills/platform-dataspace-access-configure/SKILL.md +3 -3
  114. package/skills/platform-sharing-owd-configure/SKILL.md +3 -0
  115. package/skills/platform-value-set-generate/SKILL.md +2 -0
  116. package/skills/service-agentforce-channel-configure/SKILL.md +29 -20
  117. package/skills/service-agentforce-channel-configure/assets/BotEmailDefinition.botEmailDefinition-meta.xml +36 -0
  118. package/skills/service-agentforce-channel-configure/assets/email/unfiled$public/AgentforceForServiceEmailTemplate.email +17 -0
  119. package/skills/service-agentforce-channel-configure/assets/email/unfiled$public/AgentforceForServiceEmailTemplate.email-meta.xml +29 -0
  120. package/skills/service-agentforce-channel-configure/assets/mdapi-package.xml +25 -0
  121. package/skills/service-agentforce-channel-configure/assets/settings-mdapi-package.xml +30 -0
  122. package/skills/service-agentforce-channel-configure/references/agent-wiring.md +20 -0
  123. package/skills/service-agentforce-channel-configure/references/botemaildefinition.md +107 -0
  124. package/skills/service-agentforce-channel-configure/references/channel-branch-email.md +203 -50
  125. package/skills/service-agentforce-channel-configure/references/channel-types.md +30 -3
  126. package/skills/service-agentforce-channel-configure/references/queue-resolution.md +17 -8
  127. package/skills/service-agentforce-channel-configure/references/routing-flow.md +14 -3
  128. package/skills/service-agentforce-channel-configure/scripts/validate-botemaildefinition.py +126 -0
  129. package/skills/service-agentforce-channel-configure/scripts/validate-emailtemplate.py +133 -0
  130. package/skills/service-de-channel-activate/SKILL.md +271 -0
  131. package/skills/service-de-channel-activate/references/gotchas.md +31 -0
  132. package/skills/service-de-channel-activate/references/phone-verification.md +96 -0
  133. package/skills/service-de-channel-activate/references/worked-examples.md +14 -0
  134. package/skills/service-de-channel-consent-configure/SKILL.md +230 -0
  135. package/skills/service-de-channel-consent-configure/references/gotchas.md +41 -0
  136. package/skills/service-de-channel-consent-configure/references/language-keywords.md +84 -0
  137. package/skills/service-de-channel-consent-configure/references/worked-examples.md +134 -0
  138. package/skills/service-de-channel-create/SKILL.md +369 -0
  139. package/skills/service-de-channel-create/references/apple.md +59 -0
  140. package/skills/service-de-channel-create/references/connect-insert.md +84 -0
  141. package/skills/service-de-channel-create/references/facebook.md +154 -0
  142. package/skills/service-de-channel-create/references/line.md +66 -0
  143. package/skills/service-de-channel-create/references/sms.md +98 -0
  144. package/skills/service-de-channel-create/references/whatsapp.md +98 -0
  145. package/skills/service-de-channel-create/references/worked-examples.md +70 -0
  146. package/skills/service-de-channel-routing-configure/SKILL.md +345 -0
  147. package/skills/service-de-channel-routing-configure/references/asa-routing.md +90 -0
  148. package/skills/service-de-channel-routing-configure/references/gotchas.md +27 -0
  149. package/skills/service-de-channel-routing-configure/references/queue-creation.md +123 -0
  150. package/skills/service-de-channel-routing-configure/references/target-locate.md +98 -0
  151. package/skills/service-de-channel-routing-configure/references/worked-examples.md +174 -0
  152. package/skills/service-de-headless-channel-configure/SKILL.md +305 -0
  153. package/skills/service-de-headless-channel-configure/references/gotchas.md +27 -0
  154. package/skills/service-de-headless-channel-configure/references/inputs.md +49 -0
  155. package/skills/service-de-headless-channel-configure/references/output-envelopes.md +53 -0
  156. package/skills/service-de-headless-channel-configure/references/partial-success.md +24 -0
  157. package/skills/service-de-headless-channel-configure/references/terms-and-conditions.md +54 -0
  158. package/skills/service-de-headless-channel-configure/references/worked-examples.md +108 -0
  159. package/skills/service-de-waba-integrate/SKILL.md +227 -0
  160. package/skills/service-digital-engagement-channel-configure/scripts/check-api-version.sh +29 -0
  161. package/skills/service-digital-engagement-messaging-site-integrate/SKILL.md +10 -9
  162. package/skills/service-digital-engagement-messaging-site-integrate/references/lwr_patch.md +39 -21
  163. package/skills/service-digital-engagement-messaging-site-integrate/scripts/patch_lwr_bundle.sh +157 -96
  164. package/skills/service-email-to-case-configure/SKILL.md +190 -0
  165. package/skills/service-email-to-case-configure/assets/CaseSettings.settings-meta.xml +45 -0
  166. package/skills/service-email-to-case-configure/examples/CaseSettings-two-addresses.settings-meta.xml +36 -0
  167. package/skills/service-email-to-case-configure/references/apply-mechanics.md +73 -0
  168. package/skills/service-email-to-case-configure/references/routing_address_reference.md +73 -0
  169. package/skills/service-email-to-case-configure/references/troubleshooting.md +25 -0
  170. package/skills/service-email-to-case-configure/scripts/apply-casesettings.py +1315 -0
  171. package/skills/service-email-to-case-configure/scripts/check-agent-email-capability.sh +26 -0
  172. package/skills/service-email-to-case-configure/scripts/tests/__init__.py +0 -0
  173. package/skills/service-email-to-case-configure/scripts/tests/_bootstrap.py +45 -0
  174. package/skills/service-email-to-case-configure/scripts/tests/_fakeorg.py +366 -0
  175. package/skills/service-email-to-case-configure/scripts/tests/_run.py +84 -0
  176. package/skills/service-email-to-case-configure/scripts/tests/test_apply_org_scenarios.py +655 -0
  177. package/skills/service-email-to-case-configure/scripts/tests/test_get_session.py +134 -0
  178. package/skills/service-email-to-case-configure/scripts/tests/test_new_capabilities.py +193 -0
  179. package/skills/service-email-to-case-configure/scripts/tests/test_validate_casesettings.py +170 -0
  180. package/skills/service-email-to-case-configure/scripts/validate-casesettings.py +229 -0
  181. package/skills/service-itsm-agentic-setup-agentforce-coordinate/SKILL.md +33 -15
  182. package/skills/service-itsm-agentic-setup-agentforce-coordinate/examples/output-templates.md +63 -47
  183. package/skills/service-itsm-agentic-setup-agentforce-studio-configure/SKILL.md +17 -12
  184. package/skills/service-itsm-agentic-setup-agentforce-studio-configure/references/cli-invocation.md +5 -3
  185. package/skills/service-itsm-agentic-setup-agentforce-studio-configure/scripts/classify-enable-plan.mjs +11 -3
  186. package/skills/service-itsm-agentic-setup-agentforce-studio-validate/SKILL.md +8 -6
  187. package/skills/service-itsm-agentic-setup-agentforce-studio-validate/references/cli-invocation.md +3 -3
  188. package/skills/service-itsm-agentic-setup-agentforce-studio-validate/scripts/classify-readiness.mjs +11 -3
  189. package/skills/service-itsm-agentic-setup-configure/SKILL.md +5 -5
  190. package/skills/service-itsm-agentic-setup-configure/examples/output-templates.md +5 -5
  191. package/skills/service-itsm-agentic-setup-employee-agent-configure/SKILL.md +2 -2
  192. package/skills/service-itsm-agentic-setup-employee-agent-configure/references/report-format.md +11 -7
  193. package/skills/service-itsm-agentic-setup-employee-agent-configure/scripts/render-report.mjs +20 -7
  194. package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/SKILL.md +10 -6
  195. package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/references/action-availability.md +7 -7
  196. package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/references/report-format.md +11 -7
  197. package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/scripts/build-create-body.mjs +24 -17
  198. package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/scripts/classify-action-availability.mjs +98 -58
  199. package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/scripts/render-report.mjs +20 -7
  200. package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/scripts/strip-release-management.mjs +176 -0
  201. package/skills/service-itsm-agentic-setup-itsm-agentforce-permset-assign/SKILL.md +19 -19
  202. package/skills/service-itsm-agentic-setup-itsm-agentforce-permset-assign/references/cli-invocation.md +3 -4
  203. package/skills/service-itsm-agentic-setup-itsm-agentforce-permset-assign/references/helper-contracts.md +6 -6
  204. package/skills/service-itsm-agentic-setup-itsm-agentforce-permset-assign/references/permset-topology.md +3 -10
  205. package/skills/service-itsm-agentic-setup-itsm-agentforce-permset-assign/scripts/classify-permset-availability.mjs +7 -9
  206. package/skills/service-itsm-incident-mgmt-configure/SKILL.md +2 -0
  207. package/skills/service-itsm-incident-priority-configure/SKILL.md +15 -12
  208. package/skills/service-itsm-incident-priority-configure/examples/matrix-operations.md +27 -1
  209. package/skills/service-itsm-incident-priority-configure/references/sf-cli-invocation.md +37 -6
  210. package/skills/service-native-voice-recording-transcription-configure/SKILL.md +146 -0
  211. package/skills/service-native-voice-recording-transcription-configure/assets/confirmation-output.json +16 -0
  212. package/skills/service-native-voice-recording-transcription-configure/assets/package.xml +22 -0
  213. package/skills/service-native-voice-recording-transcription-configure/references/thunderbird-voice-settings.md +101 -0
  214. package/skills/service-native-voice-recording-transcription-configure/scripts/enable-recording-transcription.sh +181 -0
  215. package/skills/data360-activate/README.md +0 -38
  216. package/skills/data360-activate/SKILL.md +0 -127
  217. package/skills/data360-connect/README.md +0 -57
  218. package/skills/data360-connect/SKILL.md +0 -163
  219. package/skills/data360-connect/examples/connections/heroku-postgres.json +0 -15
  220. package/skills/data360-connect/examples/connections/ingest-api-connection.json +0 -5
  221. package/skills/data360-connect/examples/connections/ingest-api-schema.json +0 -31
  222. package/skills/data360-connect/examples/connections/redshift.json +0 -16
  223. package/skills/data360-connect/examples/connections/sharepoint-unstructured.json +0 -20
  224. package/skills/data360-connect/examples/connections/snowflake-connection.json +0 -42
  225. package/skills/data360-harmonize/README.md +0 -31
  226. package/skills/data360-harmonize/SKILL.md +0 -126
  227. package/skills/data360-orchestrate/README.md +0 -120
  228. package/skills/data360-orchestrate/SKILL.md +0 -263
  229. package/skills/data360-orchestrate/assets/definitions/activation-target.template.json +0 -5
  230. package/skills/data360-orchestrate/assets/definitions/activation.template.json +0 -7
  231. package/skills/data360-orchestrate/assets/definitions/calculated-insight.template.json +0 -7
  232. package/skills/data360-orchestrate/assets/definitions/data-action-target.template.json +0 -5
  233. package/skills/data360-orchestrate/assets/definitions/data-action.template.json +0 -5
  234. package/skills/data360-orchestrate/assets/definitions/data-graph.template.json +0 -21
  235. package/skills/data360-orchestrate/assets/definitions/data-stream.template.json +0 -55
  236. package/skills/data360-orchestrate/assets/definitions/dmo.template.json +0 -17
  237. package/skills/data360-orchestrate/assets/definitions/identity-resolution.template.json +0 -30
  238. package/skills/data360-orchestrate/assets/definitions/mapping.template.json +0 -14
  239. package/skills/data360-orchestrate/assets/definitions/relationship.template.json +0 -12
  240. package/skills/data360-orchestrate/assets/definitions/search-index.template.json +0 -9
  241. package/skills/data360-orchestrate/assets/definitions/segment.template.json +0 -16
  242. package/skills/data360-orchestrate/references/feature-readiness.md +0 -157
  243. package/skills/data360-orchestrate/references/plugin-setup.md +0 -138
  244. package/skills/data360-orchestrate/scripts/bootstrap-plugin.sh +0 -53
  245. package/skills/data360-orchestrate/scripts/diagnose-org.mjs +0 -511
  246. package/skills/data360-orchestrate/scripts/generate-manifest.mjs +0 -68
  247. package/skills/data360-orchestrate/scripts/verify-plugin.sh +0 -58
  248. package/skills/data360-prepare/README.md +0 -50
  249. package/skills/data360-prepare/SKILL.md +0 -203
  250. package/skills/data360-prepare/examples/ingestion-api/.env.example +0 -8
  251. package/skills/data360-prepare/examples/ingestion-api/README.md +0 -48
  252. package/skills/data360-prepare/examples/ingestion-api/send-data.py +0 -144
  253. package/skills/data360-query/README.md +0 -43
  254. package/skills/data360-query/SKILL.md +0 -128
  255. package/skills/data360-query/examples/search-indexes/hybrid-structured.json +0 -44
  256. package/skills/data360-query/examples/search-indexes/vector-knowledge.json +0 -43
  257. package/skills/data360-segment/README.md +0 -35
  258. package/skills/data360-segment/SKILL.md +0 -123
  259. package/skills/service-helpagent-coordinate/references/channel-help-portal.md +0 -22
  260. /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-1-1-1-non-text-content.md +0 -0
  261. /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-1-3-1-i-lists.md +0 -0
  262. /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-1-3-1-ii-tables.md +0 -0
  263. /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-1-3-1-iii-form-labels.md +0 -0
  264. /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-1-3-1-iv-regions.md +0 -0
  265. /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-1-3-1-v-groups.md +0 -0
  266. /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-1-3-5-identify-input.md +0 -0
  267. /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-1-4-3-contrast.md +0 -0
  268. /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-2-1-1-keyboard.md +0 -0
  269. /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-2-4-4-link-purpose.md +0 -0
  270. /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-2-4-6-headings-labels.md +0 -0
  271. /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-2-5-1-pointer-gestures.md +0 -0
  272. /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-2-5-2-pointer-cancellation.md +0 -0
  273. /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-2-5-3-label-in-name.md +0 -0
  274. /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-2-5-7-dragging-movement.md +0 -0
  275. /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-3-2-1-on-focus.md +0 -0
  276. /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-3-2-2-on-input.md +0 -0
  277. /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-3-3-1-error-identification.md +0 -0
  278. /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-3-3-2-labels-instructions.md +0 -0
  279. /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-3-3-3-error-suggestion.md +0 -0
  280. /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-4-1-2-i-name.md +0 -0
  281. /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-4-1-2-ii-role.md +0 -0
  282. /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-4-1-2-iii-value.md +0 -0
  283. /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/vision/sc-1-1-1-non-text-content.md +0 -0
  284. /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/vision/sc-1-4-1-use-of-color.md +0 -0
  285. /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/vision/sc-1-4-10-resize-reflow.md +0 -0
  286. /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/vision/sc-1-4-11-non-text-contrast.md +0 -0
  287. /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/vision/sc-1-4-3-contrast.md +0 -0
  288. /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/scripts/contrast-ratio.py +0 -0
@@ -0,0 +1,241 @@
1
+ # `ask_user_tool` question templates
2
+
3
+ Every user question in the workflow MUST be dispatched via `ask_user_tool` (never printed as plain text). Copy-paste the template for the step you're on and fill in placeholders. Follow the two-part pattern from `references/ux-rules.md` when the question needs a list, table, or error detail — print structure in chat text FIRST, then call `ask_user_tool` with a single short question.
4
+
5
+ **Dispatch every `question` string VERBATIM — it is final copy, not a draft to reformat.** The `question` field renders as ONE plain paragraph: markdown is NOT interpreted, so `**bold**` prints the literal asterisks and a `-`/`1.` list collapses into run-on text. Do NOT expand a templated sentence into bullet lines, numbered lists, or bolded labels inside `question`. If you catch yourself turning `Provide the ID (Content Space IDs start with \`0Zu\`; Folder IDs start with \`9Pu\`)` into `- **Content Space ID** (0Zu…) - **Folder ID** (9Pu…)`, STOP — that reformatting IS the rendering bug users report. Any structure (tables, lists, bold) belongs ONLY in a chat-text Part 1 printed before the tool call, never in `question`.
6
+
7
+ ## Step 0-U / Step 0-P — Identifier ask (no ID supplied)
8
+
9
+ **Shared by BOTH the UPDATE direct-entry (Step 0-U) and PUBLISH direct-entry (Step 0-P) gates.** Dispatch this the instant the gate stops for a name-only request (user named the content by title/subject with no ID and it is not in the session registry). This is the ONLY template for the identifier ask — do NOT hand-write your own sentence, do NOT split the accepted-ID list into `- **Content Key**…` bullets (that is the literal-asterisk render users report), and do NOT vary the answer set between update and publish. Dispatch the `question` string VERBATIM and use these exact answers every time:
10
+
11
+ ```text
12
+ Tool: ask_user_tool
13
+ question: "Which record should I work with? Paste the content key (starts with `MC`), the Managed Content ID (starts with `20Y`), or the Variant ID (starts with `9Ps`)."
14
+ answers: ["Cancel"]
15
+ ```
16
+
17
+ The user types/pastes the identifier as free text; the single `Cancel` option lets them abort. On `Cancel`, print `Session ended.` and stop. On a pasted identifier, resolve it per `references/identifier-resolution.md` (Step 0-U → Step 8c; Step 0-P → Step 9b). Same wording, same one-option answer set on both paths — that consistency is the point.
18
+
19
+ ## Step 1 — Multi-type disambiguation (prompt spans ≥2 distinct content types)
20
+
21
+ **Dispatch ONLY when Step 1's multi-type gate fires** (the one prompt spans two or more distinct content TYPES — different content domains, NOT multiple topics/records of one type; detection rule + examples → `references/content-type-classification.md` § Multi-type gate). This is the one question Step 1 may raise. Dispatch the `question` string VERBATIM — it is fixed copy, identical every run; the only thing that varies is the answer set. Do NOT reword it, do NOT stuff the domain descriptions into `question`.
22
+
23
+ ```text
24
+ Tool: ask_user_tool
25
+ question: "Your request covers more than one kind of content. I create one content type per run — which should I create now?"
26
+ answers: ["<domain 1>", "<domain 2>", ..., "Cancel"]
27
+ ```
28
+
29
+ One answer per distinct content domain, labeled from the user's OWN words (e.g. `"Grooming packages"`, `"Service area coverage"`), plus a final `"Cancel"`. On a domain pick: carry ONLY that domain forward as `intent` into Step 2 (the other domains are dropped this run — Step 10's "Create more content" lets the user create the next one). On `Cancel`: print `Session ended.` and stop.
30
+
31
+ ## Step 2 — Bucket 3 FQN correction proposal
32
+
33
+ **When the user's content-type token is FQN-ish but the correction has more than one reasonable interpretation** (bare name without namespace, case correction, unknown namespace). Print chat text FIRST describing the ambiguity if useful, then:
34
+
35
+ ```text
36
+ Tool: ask_user_tool
37
+ question: "You provided `<original>` — this doesn't match a valid FQN format. Would you like to proceed with `<corrected>` as the content type?"
38
+ answers: ["Yes, use <corrected>", "Let me provide a different FQN", "Cancel"]
39
+ ```
40
+
41
+ Replace `<original>` and `<corrected>` with the actual literal strings. Do NOT dispatch this prompt for Bucket 2 (high-confidence near-miss) — Bucket 2 announces the correction in chat text and proceeds without a confirmation turn.
42
+
43
+ **Follow-up when the user selects "Let me provide a different FQN":**
44
+
45
+ ```text
46
+ Tool: ask_user_tool
47
+ question: "Please provide the content type FQN in `namespace__DeveloperName` format (e.g. `c__BlogPost`, `sfdc_cms__news`)."
48
+ ```
49
+
50
+ On the returned string, restart Step 2 classification from Bucket 1 (treat the new input as a fresh capture).
51
+
52
+ ## Step 3 — Workspace resolution (Question 1)
53
+
54
+ **When local UIBundles were found:**
55
+
56
+ ```text
57
+ Tool: ask_user_tool
58
+ question: "Where should I create the content? Pick a local UIBundle (I'll resolve the space automatically) or provide an ID manually."
59
+ answers: ["<masterLabel1> (<developerName1>)", "<masterLabel2> (<developerName2>)", ..., "Provide a space or folder ID manually"]
60
+ ```
61
+
62
+ One entry per discovered UIBundle formatted as `"<masterLabel> (<developerName>)"`, plus a final `"Provide a space or folder ID manually"` option.
63
+
64
+ **When no local UIBundles were found:**
65
+
66
+ ```text
67
+ Tool: ask_user_tool
68
+ question: "Which content space or folder should I create the content in? Provide the ID (Content Space IDs start with `0Zu`; Folder IDs start with `9Pu`)."
69
+ answers: ["Cancel"]
70
+ ```
71
+
72
+ The user types/pastes the ID as free text; the single `Cancel` option lets them abort. On `Cancel`, print `Session ended.` and stop (Principle 7).
73
+
74
+ **When the user picks "Provide a space or folder ID manually":**
75
+
76
+ ```text
77
+ Tool: ask_user_tool
78
+ question: "Please enter the Content Space or Folder ID (Content Space IDs start with `0Zu`; Folder IDs start with `9Pu`)."
79
+ answers: ["Go back"]
80
+ ```
81
+
82
+ **Do NOT invent placeholder tokens.** Emit the exact prefixes above (`0Zu`, `9Pu`) — do NOT fabricate patterns like `0pdXXX...` or `0apXXX...`. The screenshot regression showing `0pdXXXXXXXXXXXXX` / `0apXXXXXXXXXXXXX` was hallucinated ID prefixes that never appear in Salesforce content-space or folder IDs. When in doubt about a Salesforce ID prefix, do NOT guess — the two above are the only ones this skill supports.
83
+
84
+ If the user clicks "Go back", re-present the original Step 3 question with all UIBundle options.
85
+
86
+ **Invalid workspace ID — re-ask (format-gate fail OR server-confirmation fail).** Dispatch this the instant a manual ID fails validation: either it wasn't a 15/18-char `0Zu`/`9Pu` ID (Layer 1), or the first server call touching it returned invalid/not-found (Layer 2, incl. the sibling's `get_content_types_for_workspace` on the delegation path). This is the ONLY re-ask after a bad ID — it MUST state the ID was invalid (the neutral manual-ID prompt above does NOT; using it here is the reported "not even saying invalid" defect). Print the raw server error as chat text FIRST when Layer 2 failed, then dispatch VERBATIM, filling `<reason>`:
87
+
88
+ ```text
89
+ Tool: ask_user_tool
90
+ question: "That ID wasn't valid — <reason>. Enter a Content Space ID (starts with `0Zu`) or Folder ID (starts with `9Pu`) — must be 15 or 18 characters."
91
+ answers: ["Cancel"]
92
+ ```
93
+
94
+ `<reason>` is one of: `it wasn't a 15- or 18-character 0Zu/9Pu ID` (Layer 1 format-gate fail) OR the server error text verbatim (Layer 2 fail). On `Cancel`, print `Session ended.` and stop. Do NOT improvise an org picker or run `sf org list` (see `references/workspace-resolution.md`).
95
+
96
+ **When `get_or_create_cms_workspace_and_web_app_channel` fails for the selected UIBundle:**
97
+
98
+ ```text
99
+ Tool: ask_user_tool
100
+ question: "Could not resolve space for this UIBundle. How would you like to proceed?"
101
+ answers: ["Retry", "Pick a different option", "Provide a space or folder ID manually"]
102
+ ```
103
+
104
+ ## Step 4.B.2 — Bulk topic approval
105
+
106
+ Print the topic list as formatted chat text FIRST (numbered markdown list with title + prompt), then call:
107
+
108
+ ```text
109
+ Tool: ask_user_tool
110
+ question: "Do these topics look good?"
111
+ answers: ["Looks good, create them", "Let me adjust"]
112
+ ```
113
+
114
+ Never stuff the topic list into the `question` field — it renders as an unreadable paragraph.
115
+
116
+ ## Step 5a — Bulk pre-dispatch blanket approval
117
+
118
+ Print `Ready to create all <N> content items in your org. Proceed?` as chat text, then:
119
+
120
+ ```text
121
+ Tool: ask_user_tool
122
+ question: "Create all <N> items now?"
123
+ answers: ["Yes, create all", "Cancel"]
124
+ ```
125
+
126
+ **Do not leak dispatch mechanics.** The user asked for N content items — they see "N items." Do NOT mention parallel calls, `create_cms_content`, or the tool id in either the chat text or the `ask_user_tool` question. `"Approve all <N> create_cms_content calls?"` and `"Ready to dispatch 7 parallel create_cms_content calls to your org. Proceed?"` are both regressions — the user sees `create_cms_content` and the dispatch fan-out, both of which are internal implementation. Say `Create all 7 items now?` — NOT `Approve all 7 create_cms_content calls?`, NOT `Ready to dispatch 7 parallel create_cms_content calls`.
127
+
128
+ ## Step 7 — Post-action loop
129
+
130
+ **Single content:**
131
+
132
+ ```text
133
+ Tool: ask_user_tool
134
+ question: "What would you like to do next?"
135
+ answers: ["Edit content", "Publish content", "End session"]
136
+ ```
137
+
138
+ **Bulk content:**
139
+
140
+ ```text
141
+ Tool: ask_user_tool
142
+ question: "What would you like to do next?"
143
+ answers: ["Edit content", "Publish all", "Publish subset", "End session"]
144
+ ```
145
+
146
+ **Publish subset — item selection:**
147
+
148
+ ```text
149
+ Tool: ask_user_tool
150
+ question: "Which item numbers would you like to publish? (e.g. 1, 3, 5)"
151
+ ```
152
+
153
+ ## Step 8a — Edit scope
154
+
155
+ **Bulk edit scope:**
156
+
157
+ ```text
158
+ Tool: ask_user_tool
159
+ question: "Which content would you like to edit?"
160
+ answers: ["All items", "Specific items (by number)", "Cancel"]
161
+ ```
162
+
163
+ **Specific-items follow-up:**
164
+
165
+ ```text
166
+ Tool: ask_user_tool
167
+ question: "Which item numbers would you like to edit? (e.g. 1, 3)"
168
+ ```
169
+
170
+ ## Step 8b — Edit instructions
171
+
172
+ Free-text, and **multiple properties can be changed in one message** — the server-side pipeline reads the whole instruction and applies every change against the existing body in a single `update_cms_content_variant` call. The user does not pick fields one at a time.
173
+
174
+ If the current content body was just displayed (Step 0-U direct-entry, or Step 6 after a prior edit), the user can name fields from it. Dispatch:
175
+
176
+ ```text
177
+ Tool: ask_user_tool
178
+ question: "What would you like to change? Describe all edits in one message — you can update several fields at once (e.g. 'shorten the description, change the title to X, and add a note about Y')."
179
+ ```
180
+
181
+ Do NOT loop field-by-field and do NOT restrict the user to a single property — one free-text instruction covering any number of properties is the expected input.
182
+
183
+ ## Retry prompts
184
+
185
+ **Bulk create/update/publish partial failure — after printing failed items with prompts and errors as chat text:**
186
+
187
+ ```text
188
+ Tool: ask_user_tool
189
+ question: "How would you like to proceed?"
190
+ answers: ["Retry failed items", "Skip and continue", "End session"]
191
+ ```
192
+
193
+ **Total failure:**
194
+
195
+ ```text
196
+ Tool: ask_user_tool
197
+ question: "How would you like to proceed?"
198
+ answers: ["Retry all", "End session"]
199
+ ```
200
+
201
+ **Total failure — uniform error (Guard A from `references/error-recovery.md`).** Dispatch this variant ONLY when every one of the N failed calls returned the same error signature — the retry option is deliberately hidden because the failure is systemic. Print the uniform-error chat text from `error-recovery.md` FIRST, then:
202
+
203
+ ```text
204
+ Tool: ask_user_tool
205
+ question: "How would you like to proceed?"
206
+ answers: ["End session"]
207
+ ```
208
+
209
+ **Total failure — retry exhausted (Guard B from `references/error-recovery.md`).** Dispatch this variant ONLY on the 3rd+ consecutive total failure of the same bulk-operation instance — the retry option is deliberately hidden after two failed attempts. Print chat text FIRST: `<N> items have failed on <retryCount> consecutive attempts. Ending the session — resolve the underlying issue and re-run.` Then:
210
+
211
+ ```text
212
+ Tool: ask_user_tool
213
+ question: "How would you like to proceed?"
214
+ answers: ["End session"]
215
+ ```
216
+
217
+ ## Step 10 — Post-publish
218
+
219
+ **`workspaceMethod=uibundle` — replace `<masterLabel>` and `<developerName>` with the actual values selected in Step 3:**
220
+
221
+ ```text
222
+ Tool: ask_user_tool
223
+ question: "Content published! What would you like to do next?"
224
+ answers: ["Create more content", "Render it to the UI Bundle (<masterLabel> (<developerName>))", "End session"]
225
+ ```
226
+
227
+ **`workspaceMethod=manual` — no UIBundle was selected in Step 3, so no `channelId` is available for the render handoff. Print this one-liner as chat text FIRST so the user knows why the Render option is missing, then dispatch the prompt:**
228
+
229
+ Chat text (Part 1):
230
+
231
+ ```text
232
+ Rendering to a UI Bundle requires a UIBundle selection at the workspace step, which resolves the channel automatically. This run used a folder ID directly — to render the content, re-run this skill and pick a UIBundle at Step 3.
233
+ ```
234
+
235
+ Prompt (Part 2):
236
+
237
+ ```text
238
+ Tool: ask_user_tool
239
+ question: "Content published! What would you like to do next?"
240
+ answers: ["Create more content", "End session"]
241
+ ```
@@ -0,0 +1,81 @@
1
+ # Example `create_cms_content` payload
2
+
3
+ > **Read this first.** `sfdc_cms__article` and `0ZuKZ00000XXXXXXXX` below are **shape illustrations**, not defaults. The `contentType` FQN must come from `experience-cms-content-type-generate` against the live org — never copy the FQN from this file. The `contentSpaceOrFolderId` value comes from the user's answer to the Step 3 workspace question — never from a local file. A workspace will reject any type it isn't configured to support, so picking an FQN from training data or this example will fail with `"These content type(s) X are not supported by this space"`.
4
+
5
+ The `experience-cms-content-generate` skill dispatches `create_cms_content` with the user's goal on the **`prompt` channel**. The server-side pipeline (Vibes MC content pipeline) generates and validates the body against the type's schema. The agent generates only the `title` and shapes the payload.
6
+
7
+ ## Example
8
+
9
+ User asked: *"Draft an article announcing our Q4 product launch — make it about the new analytics dashboard. Cover the problem it solves, three headline features (real-time KPIs, drill-down by segment, export to spreadsheet), availability date, and a call-to-action linking to the product page."*
10
+
11
+ Assume `experience-cms-content-type-generate` returned `contentTypeFqn: sfdc_cms__article`.
12
+
13
+ Agent generates only a title from `[USER GOAL]`:
14
+
15
+ - **Title:** `Q4 Launch — Analytics Dashboard`
16
+
17
+ Payload:
18
+
19
+ ```json
20
+ {
21
+ "inputs": [
22
+ {
23
+ "contentType": "sfdc_cms__article",
24
+ "contentSpaceOrFolderId": "0ZuKZ00000XXXXXXXX",
25
+ "title": "Q4 Launch — Analytics Dashboard",
26
+ "prompt": "Draft an article announcing our Q4 product launch — make it about the new analytics dashboard. Cover the problem it solves, three headline features (real-time KPIs, drill-down by segment, export to spreadsheet), availability date, and a call-to-action linking to the product page."
27
+ }
28
+ ]
29
+ }
30
+ ```
31
+
32
+ Notes:
33
+
34
+ - **`title` reflects `[USER GOAL]`.** Not the user's message verbatim — the message was an authoring instruction, not a title.
35
+ - **`prompt` is `[USER GOAL]` verbatim.** Do not paraphrase, trim, or reformat — the server-side pipeline parses it directly.
36
+ - **No `contentBody` field.** `prompt` and `contentBody` are mutually exclusive; sending both fails. This skill never sends `contentBody`.
37
+ - **No client-side pre-flight validation.** The server owns validation.
38
+ - Single-element `inputs` array — the skill creates one record per element. **Bulk creation dispatches N separate `create_cms_content` calls in parallel, each with a 1-element `inputs` array** — one call per item is the hard rule (never combine items into a multi-element `inputs` array). See SKILL.md Step 5b and `references/bulk-batching.md`.
39
+
40
+ ### Optional fields
41
+
42
+ These pass through only when the user explicitly named them:
43
+
44
+ ```json
45
+ {
46
+ "inputs": [
47
+ {
48
+ "contentType": "<from-sibling>",
49
+ "contentSpaceOrFolderId": "<from-user-step-3>",
50
+ "title": "<agent-generated>",
51
+ "prompt": "<[USER GOAL] verbatim>",
52
+ "urlName": "q4-launch-analytics-dashboard"
53
+ }
54
+ ]
55
+ }
56
+ ```
57
+
58
+ ### Successful response (abridged)
59
+
60
+ ```json
61
+ {
62
+ "outputs": [
63
+ {
64
+ "managedContentId": "20YKZ00000XXXXXXXX",
65
+ "managedContentVersionId": "20XKZ00000XXXXXXXX",
66
+ "managedContentVariantId": "20ZKZ00000XXXXXXXX",
67
+ "contentKey": "MCRT_a1B2c3D4",
68
+ "contentFqn": "sfdc_cms__article",
69
+ "title": "Q4 Launch — Analytics Dashboard",
70
+ "urlName": "q4-launch-analytics-dashboard",
71
+ "apiName": "Q4_Launch_Analytics_Dashboard",
72
+ "contentSpace": { "id": "0ZuKZ00000XXXXXXXX", "label": "Marketing" },
73
+ "createdBy": { "id": "005KZ00000XXXXXXXX", "name": "Jane Doe" },
74
+ "createdDate": "2026-11-01T17:42:08.000Z",
75
+ "contentBody": { "title": "Q4 Launch — Analytics Dashboard", "body": "<h2>…</h2>", "excerpt": "…" }
76
+ }
77
+ ]
78
+ }
79
+ ```
80
+
81
+ The skill surfaces (at minimum) `title`, `contentKey`, `managedContentId`, `contentFqn`, and `contentSpace.label` — those are what the user needs to find the record again. Response latency is server-side-generation dependent — not guaranteed sub-second like a pure persist path.
@@ -0,0 +1,56 @@
1
+ # Bulk Dispatch Rules — `create_cms_content` / `update_cms_content_variant`
2
+
3
+ Single source of truth for how bulk operations are dispatched. Referenced from SKILL.md Step 5b.
4
+
5
+ ## The rule in one sentence — HARD RULE
6
+
7
+ **Dispatch exactly ONE `create_cms_content` call per item, with a 1-element `inputs` array, and fan out all N calls in parallel in a single turn.** No exceptions, no thresholds, no batching, no grouping.
8
+
9
+ This applies for every N ≥ 1. Single content (N=1) is one call; bulk (N ≥ 2) is N calls, dispatched in parallel.
10
+
11
+ ## Why one-call-per-item
12
+
13
+ - **Matches the server-side generation model.** Each `create_cms_content` runs the Vibes MC content pipeline for one record; keeping calls 1:1 with records means one server-side generation per wire call, which is how the pipeline is tuned.
14
+ - **Bounded blast radius = 1.** A dropped connection loses exactly one record. Retry is trivial — the same 1-element payload, redispatched.
15
+ - **Trivial partial-failure handling.** Each call's success or failure is independent and known individually. No need to walk an `outputs` array or reconcile which sub-item failed.
16
+ - **Simpler mental model for the skill.** No batch-size math, no balancing, no re-batching on retry.
17
+
18
+ ## Do NOT
19
+
20
+ - **Do NOT put more than one element in `inputs`.** Even for N=2, do NOT send one `create_cms_content` with a 2-element `inputs` array. Every call is exactly one element.
21
+ - **Do NOT serialize.** For N ≥ 2, dispatch all N calls in the same turn in parallel — do not dispatch call 1, await, then dispatch call 2. Serialization defeats the parallelism this rule enables.
22
+ - **Do NOT batch on retry.** If items 3 and 7 failed, retry them as two separate parallel 1-element calls — never combine into a single 2-element `inputs` array.
23
+ - **Do NOT mention dispatch mechanics to the user.** The user asked for N content items — they see "N items." Do NOT mention parallel calls, `create_cms_content`, or the tool id. Say `Ready to create 7 items` — NOT `Ready to dispatch 7 parallel create_cms_content calls`.
24
+ - **Do NOT narrate tool preparation.** If the runtime lazy-loads `create_cms_content` at dispatch time, do the tool-schema fetch inside the same turn as 5b — no `"Let me load the content creation tool"`, no `"Loading tool schema"`, no `"Fetching create_cms_content"`. The user should see the dispatched results, not the plumbing that got you there.
25
+
26
+ ## Same shape applies to `update_cms_content_variant`
27
+
28
+ Bulk edits (Step 8d) follow the same rule: one `update_cms_content_variant` call per selected item, 1-element `inputs`, all N dispatched in parallel. Each call carries its own `variantId` + its own `prompt`.
29
+
30
+ ## Bulk topic generation + approval (Step 4, quantity > 1)
31
+
32
+ Referenced from SKILL.md Step 4 "Bulk Content". Runs before the parallel dispatch above.
33
+
34
+ **4.B.1. Generate topic prompts.** Generate N distinct topic prompts (N = explicit count, or 4–5 if unspecified), each a unique angle within the user's domain.
35
+
36
+ **4.B.2. Present topics for approval — TWO-PART output.**
37
+
38
+ Part 1 — print the topic list as formatted chat text (markdown) so line breaks and numbering render:
39
+
40
+ ```markdown
41
+ I'll create **<N>** content items of type `<FQN>`. Here are the topics:
42
+
43
+ 1. **<short title 1>** — <topic prompt 1>
44
+ 2. **<short title 2>** — <topic prompt 2>
45
+ 3. **<short title 3>** — <topic prompt 3>
46
+
47
+ You can approve as-is, remove items by number, add new topics, or rewrite any prompt.
48
+ ```
49
+
50
+ Part 2 — immediately after the text, dispatch the Step 4.B.2 approval prompt from `assets/questions.md`. Never put the full topic list inside the `ask_user_tool` question (see `references/ux-rules.md`).
51
+
52
+ **4.B.3. Handle response.**
53
+ - `Looks good, create them` → proceed to 4.B.4 with the listed prompts.
54
+ - `Let me adjust` → wait for the user's modifications (remove / add / rewrite), then re-present the final list for a single confirmation. Do NOT loop more than once — after the second presentation, proceed with whatever the user confirms.
55
+
56
+ **4.B.4. Prepare N single-item payloads.** Use `assets/payloads/create-content-bulk.json` as the per-call shape — build N independent 1-element `inputs` payloads (one per approved topic). All share the same `contentType` and `contentSpaceOrFolderId`; each carries its own `title` (agent-generated for that topic) and `prompt` (that topic's approved prompt verbatim). Step 5b dispatches those N calls in parallel per the HARD RULE above.
@@ -0,0 +1,88 @@
1
+ # Step 2 — content-type classification buckets (full detail)
2
+
3
+ Step 2 classifies Step 1's captured content-type reference into one of four buckets. Buckets 1/2/3 are fast-paths (skip the sibling); Bucket 4 delegates.
4
+
5
+ ## Bucket 1 — Exact FQN
6
+
7
+ Token matches `^[a-zA-Z_][a-zA-Z0-9_]*__[A-Za-z][A-Za-z0-9_]*$` exactly (e.g. `c__BlogPost`, `sfdc_cms__news`, `my_ns__CustomerStory`). Capture `contentTypeFqn = "<user's token>"` and go directly to Step 3. **Silent — no chat text, no confirmation prompt.**
8
+
9
+ ## Bucket 2 — High-confidence auto-correctable near-miss
10
+
11
+ Token is a clear FQN with a mechanical typo where the correction is unambiguous — exactly one reasonable interpretation. Detection: **single-underscore separator between a recognizable namespace and a developer name.** Recognizable namespaces = `c` (default custom), `sfdc_cms` (standard CMS), or any namespace-prefix pattern matching `^[a-z][a-z0-9_]{0,14}$` where the segment before the single underscore looks like a namespace identifier and the segment after starts with an alphabetic character. Correction: replace the single underscore between namespace and developer name with `__`. Qualifies: `c_news`, `sfdc_cms_news`, `myns_BlogPost`. Does NOT qualify: `blog_post` (both segments look like developer-name words), `news_article_topic` (three-segment, no confident split).
12
+
13
+ Auto-correct silently, then **announce in chat text**: `You provided \`<original>\` — this isn't a valid FQN format. Proceeding with \`<corrected>\` as the content type. If this isn't right, cancel and re-run with the correct FQN.` Then go directly to Step 3 with `contentTypeFqn = "<corrected>"`. **Do NOT dispatch an `ask_user_tool` prompt for Bucket 2** — single-answer mechanical correction; asking wastes a turn.
14
+
15
+ ## Bucket 3 — Medium/low-confidence FQN-ish token
16
+
17
+ Token looks like a naming attempt but has more than one reasonable interpretation. Falls into Bucket 3 if any of the following is true AND it is not already Bucket 1 or 2:
18
+
19
+ - **Bare developer name with no namespace** (e.g. `BlogPost`, `News`, `PressRelease`) — could be `c__BlogPost` or `<managed>__BlogPost`. Default proposal: prepend `c__`.
20
+ - **Unknown namespace with a single-underscore separator** where the left segment doesn't obviously match a namespace pattern (e.g. `foobar_thing`). Propose the double-underscore version; user confirms.
21
+
22
+ **Case does NOT trigger Bucket 3.** Salesforce API names — including ContentTypeBundle FQNs — are case-insensitive at lookup, so `c__BlogPost`, `C__blogpost`, `c__BLOGPOST` all resolve to the same record. Any token matching the Bucket 1 regex is Bucket 1 — do NOT propose a "case correction" via Bucket 3 (it would burn an `ask_user_tool` turn for zero functional effect).
23
+
24
+ For Bucket 3, dispatch the **Step 2 FQN-correction prompt** from `assets/questions.md` (`Yes, use <corrected>` / `Let me provide a different FQN` / `Cancel`). Route:
25
+
26
+ - `Yes, use <corrected>` → capture `contentTypeFqn = "<corrected>"`, go to Step 3.
27
+ - `Let me provide a different FQN` → dispatch the follow-up "provide FQN" prompt from `assets/questions.md`. On the returned string, restart Step 2 classification from Bucket 1 (treat as a fresh Step 1 capture).
28
+ - `Cancel` → **STOP silently.** Print `Session ended.` and exit.
29
+
30
+ ## Invalid-FQN gate — a token that MEANT to be an FQN but is malformed
31
+
32
+ Before falling to Bucket 4, catch a token the user clearly intended as an FQN (contains `__`, or a namespace-style `<seg>__<seg>` shape) but which does NOT match the Bucket 1 regex and is NOT a Bucket 2 single-underscore near-miss — e.g. `c__` (empty developer name), `__BlogPost` (empty namespace), `c__Blog Post` (space in name), `c__123` (developer name starts with a digit), `c____Post` (doubled separator). These are broken FQNs, not natural-language phrases — do NOT silently delegate them to the sibling as free text (the sibling would treat the garbage as a search phrase). Instead dispatch the **Step 2 FQN-correction prompt** from `assets/questions.md`: show the invalid token, offer `Let me provide a different FQN` and `Cancel` (omit a "use `<corrected>`" option when there is no confident single correction). On `Let me provide a different FQN`, dispatch the follow-up "provide FQN" prompt and restart Step 2 from Bucket 1 on the new string. A token with NO FQN punctuation at all (`blog post`, `news article`) is genuine natural language → Bucket 4, not this gate.
33
+
34
+ ## Bucket 4 — Natural-language type name or no token
35
+
36
+ Token is a free-text phrase (`"blog post"`, `"news article"`, `"customer story"`) or Step 1 captured no content-type reference at all. Delegate to `experience-cms-content-type-generate` — proceed to Step 2a.
37
+
38
+ ## Fast-path invariants (Buckets 1, 2, 3)
39
+
40
+ Once a fast-path bucket captured the FQN, do NOT: verify it exists in the org (the `INVALID_TYPE` response at Step 5 IS the verification), delegate to the sibling (the FQN IS the answer), scan `contentTypes/` locally, dispatch `metadata-grounding.search_metadata`, run `sf project retrieve start`, or read `schema.json` from disk. If the FQN doesn't resolve, `create_cms_content` fails with `INVALID_TYPE` — see `references/error-recovery.md`.
41
+
42
+ ## Multi-type gate (Step 1 — fires BEFORE classification)
43
+
44
+ A single prompt sometimes names **two or more distinct content TYPES** (e.g. `Create content covering the grooming packages and the service area coverage` → a grooming-package type AND a service-area type). This skill resolves **one content type per run** — the delegation contract passes ONE `intent` and consumes ONE `{status, fqn}`. Attempting to resolve two types in one run is sequencing drift (the sibling emits one outcome; a second in-turn resolution corrupts its state machine). So when the prompt spans multiple types, ask the user to pick ONE before Step 2.
45
+
46
+ **TRIGGER (ask) — the prompt maps to ≥2 distinct content types.** Judge by content domain, not word count. Distinct domains that would each be their own `ContentTypeBundle`:
47
+
48
+ - `grooming packages` **and** `service area coverage` → grooming-service type + service-area type → **ASK**
49
+ - `a product page and an FAQ` → product type + FAQ type → **ASK**
50
+ - `event details plus a press release` → event type + press-release type → **ASK**
51
+
52
+ **DO NOT trigger (stay silent — existing paths) — one type, no matter the topic/quantity count:**
53
+
54
+ - `5 blog posts about our launch` → ONE type (blog), bulk of 5 records → silent, existing bulk path
55
+ - `a blog about cheese and wine` → ONE type (blog), two subjects in one record/topic set → silent
56
+ - `news articles on X, Y, and Z` → ONE type (news), three topics → silent (bulk topic generation owns this)
57
+ - any single-domain prompt → silent
58
+ - FQN provided (Buckets 1/2/3) → the fast-path already fixed the type; the gate does NOT run
59
+
60
+ **The distinction:** multiple *content types* → ASK; multiple *topics/records of one type* → silent (bulk owns it). If unsure whether two domains are really different types, prefer to ASK — a false ask costs one extra turn; a false silence resurfaces the two-types-in-one-run drift.
61
+
62
+ **On the pick:** carry ONLY the chosen domain forward as the `intent` into Step 2 (all downstream steps — classification, delegation, create — see exactly one domain, so every existing invariant holds unchanged). The dropped domain(s) are NOT lost — Step 10's post-publish "Create more content" lets the user create the next type in a fresh run. Question template (fixed copy, verbatim every run) → `assets/questions.md` § Step 1.
63
+
64
+ **This is the ONLY exception to Step 1's "never ask" rule.** It does NOT reopen the general clarifying-questions regression: it fires solely on the objective ≥2-distinct-types condition, never for goal refinement, mode, body details, "do you have a type in mind?", or quantity. If you are asking anything other than "which of these N distinct types," that is the Step 1 anti-pattern, not this gate.
65
+
66
+ ## What the sibling owns (delegated path only)
67
+
68
+ When the fast-path does not apply, this skill hands the user's intent to `experience-cms-content-type-generate` and waits for exactly one of four terminal outcomes (`success` / `not_deployed` / `cancelled` / `error`). All of the following are the sibling's job:
69
+
70
+ - Local `contentTypes/` scan and `metadata-grounding` lookup
71
+ - The user-facing pick question when multiple candidates match
72
+ - Creating a new `ContentTypeBundle` when nothing matches, and asking to deploy it
73
+ - Constructing the namespace-prefixed FQN after a deploy
74
+ - Retrieve-and-reconcile against the org copy, drift resolution
75
+
76
+ ## Drift-safety net (delegated path) — five signals that delegation is broken
77
+
78
+ The harness cannot enforce delegation between two markdown skills, so treat every one of these as a hard stop and route to Step 2b's `load failed` row instead of doing the sibling's work:
79
+
80
+ 1. Constructing a `search_metadata` query for `ContentTypeBundle` yourself.
81
+ 2. Running `find` / `ls` / `cat` (or `Read`) against `contentTypes/`, `schema.json`, or any local content-type-bundle file to answer "what FQN should I use?".
82
+ 3. Running `sf project retrieve start` for `ContentTypeBundle` metadata.
83
+ 4. Dispatching `create_cms_content` (Step 4+) without a sibling-emitted (or fast-path-captured) `contentTypeFqn` in hand. (Resolving the workspace via `get_or_create_cms_workspace_and_web_app_channel` BEFORE the FQN is expected on the delegation path — that ID is passed to the sibling — and is NOT drift.)
84
+ 5. Dispatching `create_cms_content` with an FQN reconstructed from a folder name, a `schema.json` filename, or a local scan result.
85
+
86
+ If drift #1 has already happened despite this rule, then since the harness cannot enforce delegation, the query construction rules live in a single shared file so the wrong-skill outcome is at least a right query. Read `../experience-cms-content-type-generate/references/discovery-query-rules.md` before emitting any `search_metadata` call. Common bug queries this file exists to prevent: `"CMS content type bundle"`, `"content type bundle"`, `"<domain> content type"` — any query containing the words `content type`, `bundle`, or `CMS` is filler-only and has stripped out the intent.
87
+
88
+ **Do not** downgrade `not_deployed` to `success` because "the bundle is validated and the FQN is predictable." A local-only bundle is not in the org; `create_cms_content` returns `INVALID_TYPE` and the user sees a confusing error two turns later. Trust the sibling's status verbatim.
@@ -0,0 +1,95 @@
1
+ # `create_cms_content` — content-write MCP tool reference
2
+
3
+ The CMS content-creation capability is exposed as a tool on the `content-write` MCP server. The canonical tool id is `create_cms_content`; the underlying Connect API operation is `createManagedContent` → `POST /connect/cms/contents`. IDE-specific namespace prefixes vary (e.g. `mcp__content-write__create_cms_content` in some surfaces) — refer to it by capability and the canonical id, not by a single hardcoded full name.
4
+
5
+ ## Authoritative source: the JSON input schema
6
+
7
+ The tool's prose description sometimes lists `contentBody` and `title` as required. **The JSON input schema is authoritative — the prose is not.** The schema declares only `contentType` and `contentSpaceOrFolderId` as required, and offers two mutually exclusive body channels (`prompt` xor `contentBody`).
8
+
9
+ **This skill uses the `prompt` channel exclusively for both `create_cms_content` and `update_cms_content_variant`.** The user's goal (create) or edit instruction (update) is passed to the tool as `prompt`; the tool's server-side pipeline (Vibes MC content pipeline) owns generation / edit application and schema validation. The agent generates only the `title` on the create path, and only re-emits `title` on the edit path when the edit clearly targets the title. This skill does not use `contentBody` on any dispatch. `update_cms_content_variant` accepts `prompt` and reads the existing `contentBody` for the target `variantId`; the server applies the edit and persists the result.
10
+
11
+ ## Inputs
12
+
13
+ The tool accepts an `inputs` array; each element persists one content record. **This skill sends exactly ONE element per call** — for bulk creation of N items, it dispatches N separate `create_cms_content` calls in parallel, each carrying a 1-element `inputs` array. See "Dispatch policy" below.
14
+
15
+ ## Dispatch policy — one call per item, parallel fan-out (HARD RULE)
16
+
17
+ For any N ≥ 1, dispatch N `create_cms_content` calls, each with a 1-element `inputs` array, all fanned out in parallel in a single turn. Enforced by SKILL.md Step 5b and detailed in `references/bulk-batching.md`.
18
+
19
+ **Why one call per item:**
20
+
21
+ - **Matches the server-side generation model.** Each `create_cms_content` runs the Vibes MC content pipeline for one record; 1:1 calls-to-records is how the pipeline is tuned.
22
+ - **Blast radius = 1.** A dropped connection loses exactly one record. Retry is trivial — the same 1-element payload, redispatched.
23
+ - **Trivial partial-failure handling.** Each call's success or failure is independent and known individually.
24
+ - **Simpler mental model.** No batch-size math, no balancing, no re-batching on retry.
25
+
26
+ **Anti-patterns:**
27
+
28
+ - Any `inputs` array with more than 1 element — violates the hard rule. Split into N parallel 1-element calls.
29
+ - Serialized calls (dispatch call 1, await, dispatch call 2, …) — defeats the parallelism this rule enables.
30
+ - Combining failed retries into a multi-item `inputs` array — retry each failed item as its own 1-element parallel call.
31
+
32
+ ### Required per element
33
+
34
+ | Key | Type | Notes |
35
+ |-----|------|-------|
36
+ | `contentType` | string | Fully qualified type name. Standard: `sfdc_cms__article`. Custom: `<namespace>__<TypeName>`, e.g. `c__PressRelease`. The masterLabel is **not** accepted here. The FQN must come from the `experience-cms-content-type-generate` sibling — never copy from this doc. |
37
+ | `contentSpaceOrFolderId` | string | Salesforce ID of the target content space (workspace) or a folder within one. Org-specific — do not reuse across orgs. Always asked from the user (see SKILL.md Step 3). Never inferred from `ui-bundle.json` or any local file. |
38
+ | `title` | string | Agent-generated — reflects `[USER GOAL]`. |
39
+ | `prompt` | string | **The body channel this skill uses.** `[USER GOAL]` verbatim. The server-side pipeline generates and validates the body against the type's schema. Mutually exclusive with `contentBody`. |
40
+
41
+ ### Body channel policy
42
+
43
+ This skill emits `prompt` only. `contentBody` (caller-supplied JSON body serialized to a string) is a valid tool input but is not used here — the server-side pipeline owns generation quality end-to-end.
44
+
45
+ **Mutual exclusion.** `prompt` and `contentBody` cannot both be set on the same `inputs[]` element. Sending both fails; sending neither fails.
46
+
47
+ ### Optional per element
48
+
49
+ | Key | Type | When to set |
50
+ |-----|------|-------------|
51
+ | `urlName` | string | URL-friendly slug within the org. Set when you want a deterministic URL; default to lowercase-kebab-case derived from `title`. |
52
+ | `contentKey` | string | Specific content key to assign. The tool auto-generates one if omitted — prefer omission unless the user has a key in hand. |
53
+ | `externalId` | string | External-system correlation id. Pass through only when the user supplies it. |
54
+ | `apiName` | string | API name of the content. Rarely needed — let the tool pick a default. |
55
+
56
+ ## Consuming the outcome from `experience-cms-content-type-generate`
57
+
58
+ The sibling skill returns a structured outcome. This skill consumes only `{ status, fqn, message }`. The sibling may also emit `schema`, but this skill ignores it — server-side generation does not need it. See SKILL.md Step 2b/2c for the routing table.
59
+
60
+ ## Response shape
61
+
62
+ A successful call returns a nested object on the matching `outputs` element. Key fields the skill surfaces:
63
+
64
+ | Field | What it is |
65
+ |-------|------------|
66
+ | `managedContentId` | The record's primary id — pass this to any follow-up tooling. |
67
+ | `managedContentVersionId` | Version-specific id (a record may have multiple versions). |
68
+ | `managedContentVariantId` | Variant id (language/locale variant). |
69
+ | `contentKey` | Stable key the user references in URLs and other content. |
70
+ | `contentFqn` | Echo of the `contentType` FQN. |
71
+ | `title` | Final title. |
72
+ | `urlName` | Final url-friendly slug. |
73
+ | `contentSpace` | Object with `id` and `label` of the parent workspace. |
74
+ | `folder` | Object with `id` and `label` if a folder was used. |
75
+ | `createdBy`, `createdDate`, `lastModifiedBy`, `lastModifiedDate` | Standard audit fields. |
76
+ | `contentBody` | The persisted body (echoes back what was stored). |
77
+ | `contentVersion` | Version-related metadata. |
78
+
79
+ Optional fields are omitted when not applicable — do not assume every key is present.
80
+
81
+ ## Out-of-scope siblings on `content-write`
82
+
83
+ The same MCP server exposes other tools — of these, `update_cms_content_variant` and `publish_content` are used by this skill (see SKILL.md Steps 8 and 9). The rest are out of scope:
84
+
85
+ | Tool id | What it does | Where it belongs |
86
+ |---------|--------------|------------------|
87
+ | `unpublish_content` | Unpublishes from channels | Out of scope |
88
+ | `clone_content` | Clones an existing record | Out of scope |
89
+ | `create_workspace` | Creates a content space | Out of scope (workspace tooling) |
90
+ | `update_workspace` | Updates a workspace | Out of scope |
91
+ | `update_workspace_channels` | Sets workspace channel mapping | Out of scope |
92
+ | `create_channel` | Creates a delivery channel | Out of scope |
93
+ | `update_channel` | Updates a channel | Out of scope |
94
+
95
+ If the user asks for any of these, exit this skill cleanly and point them at the appropriate tool or the CMS UI.
@@ -0,0 +1,37 @@
1
+ # Step 2 delegation protocol (Bucket 4) — full detail
2
+
3
+ SKILL.md Step 2 keeps the classification-bucket summary, the fast-path invariants, and the 2b `status` routing table (load-bearing). This file holds the full procedural detail for the delegated path: 2a (hand over the intent), 2c (handoff validation), and 2d (what NOT to do).
4
+
5
+ ## 2a. Hand over the intent — first tool call after Step 1, no user turn between
6
+
7
+ **Only reached on Bucket 4 (natural-language or no content-type reference).** If Bucket 1/2/3 resolved the FQN, you are at Step 3 — do not enter Step 2a.
8
+
9
+ **Resolve the workspace FIRST, before delegating.** The sibling scopes discovery via `get_content_types_for_workspace`, so it needs the space up front. Run Step 3 now — the workspace question and (for a UIBundle pick) `get_or_create_cms_workspace_and_web_app_channel` — to capture `contentSpaceOrFolderId` before the sibling call. That workspace question is the ONE `ask_user_tool` allowed before delegation; a vague prompt (`generate new content for Q4 launch`) is a valid intent, not a reason to clarify. Then delegate.
10
+
11
+ **Print a one-line banner BEFORE delegating** so the user sees the handoff (the sibling runs silently): `Resolving the content type for your request…`. One line, no planning prose.
12
+
13
+ **Invocation — use the MCP skill bridge, not the built-in `Skill` tool.** Dispatch via `mcp__skill_bridge__load_skill("experience-cms-content-type-generate")`. The built-in `Skill` tool uses a separate registry that returns `Unknown skill` for bridge skills. Load failure → route as `load failed` in Step 2b; do NOT do the sibling's work here.
14
+
15
+ Pass `{ intent: "<user's original message verbatim>", suppressCreateContentPrompt: true, <scope> }` — `<scope>` is the resolved `contentSpaceOrFolderId` keyed by prefix: `0Zu` → `spaceId: "<id>"`; `9Pu` → `folderId: "<id>"`. This scopes the sibling's `get_content_types_for_workspace` so it offers only types that space supports. **This call is the Layer-2 server confirmation of a manual space** — an invalid/not-found error (`INVALID_API_INPUT` / "must be a valid ManagedContentSpace id" / space-not-found) is a **HARD STOP: do NOT let the sibling build/deploy a type on a bad space.** Surface verbatim, re-ask via the invalid-ID template before re-dispatch. → `references/workspace-resolution.md` § Validate. **Pass exactly one of `spaceId`/`folderId`, never also `baseType`** (mutually exclusive). The sibling runs discovery, disambiguates, offers create-new if nothing matches. **Pass the message verbatim — no paraphrase, no "The user wants…" prefix.**
16
+
17
+ **Anti-pattern — no pre-delegation question.** The moment you have `intent` verbatim, the sibling call goes out. Do NOT confirm intent, ask if they have a type in mind, or run a "few clarifying questions" preamble — documented regressions. Delegate.
18
+
19
+ ## 2b. Consume the structured outcome — delegation boundary
20
+
21
+ **Delegation boundary — do not execute any later step while the sibling is running.** Once Step 2a dispatches the sibling, this skill is paused: do NOT run Step 4 or any later step until the sibling emits a terminal outcome. Interleaving is sequencing drift — parent and child share one thread; any parent tool call mid-delegation corrupts the sibling's state machine. Wait for the sibling's next turn.
22
+
23
+ The sibling emits every terminal state as a structured outcome. **This skill consumes `{ status, fqn, message }` — the sibling may also emit `schema`, but this skill ignores it (server-side generation does not need it).** The `status` routing table lives in SKILL.md § Step 2b.
24
+
25
+ The `load failed` row (bridge returned `Unknown skill` / bridge error — sibling never ran): **STOP.** Print: `Cannot proceed — the required sibling skill experience-cms-content-type-generate is not available on this bridge. Exit and re-run once the sibling is registered.` Sibling-unavailable is a terminal failure, NOT a fallback trigger. Do NOT scan `contentTypes/` locally, do NOT `cat schema.json`, do NOT dispatch `metadata-grounding.search_metadata` for `ContentTypeBundle`, do NOT call `get_or_create_cms_workspace_and_web_app_channel`, do NOT continue to Step 3. If the initial load-via-name failed but the sibling is discoverable via `mcp__skill_bridge__search_skills`, retry once via `mcp__skill_bridge__load_skill` with the exact name from the search result before treating it as terminal.
26
+
27
+ ## 2c. Handoff validation (defensive — only on `status: success`)
28
+
29
+ Even under `success`, verify `fqn` is usable before continuing — a malformed handoff must not silently poison Step 4:
30
+
31
+ - **`fqn`** — non-empty string matching `^[a-zA-Z_][a-zA-Z0-9_]*__[A-Za-z][A-Za-z0-9_]*$`. If missing or malformed, surface: `Received a success outcome from experience-cms-content-type-generate but the FQN is missing or malformed. Re-run, or provide the FQN directly.` — then `ask_user_tool`: `Retry with an explicit FQN` / `Cancel`.
32
+
33
+ Only after the check passes, capture `contentTypeFqn` and continue to Step 3.
34
+
35
+ ## 2d. What NOT to do
36
+
37
+ **Do not** call `metadata-grounding`, run `sf project retrieve`, re-present candidate lists, ask the user to re-pick a type, or construct FQNs from folder names — the sibling owns discovery, FQN-provide, retrieve-and-reconcile, and drift resolution. **Drift-safety net — five signals, any one means delegation is broken; hard-stop and route to Step 2b's `load failed` row → `references/content-type-classification.md` § Drift-safety net.** Do NOT downgrade `not_deployed` to `success` — a local-only bundle fails `INVALID_TYPE`.