@salesforce/afv-skills 1.45.0 → 1.47.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 (171) hide show
  1. package/package.json +1 -1
  2. package/skills/agentforce-observe/SKILL.md +32 -4
  3. package/skills/agentforce-observe/references/ahm-alerts.md +719 -0
  4. package/skills/automation-flow-generate/SKILL.md +11 -5
  5. package/skills/consumer-goods-promotion-bo-api-deploy/SKILL.md +275 -0
  6. package/skills/consumer-goods-promotion-bo-api-deploy/assets/set-comment-value/README.md +32 -0
  7. package/skills/consumer-goods-promotion-bo-api-deploy/assets/set-comment-value/SetCommentValue.cls +75 -0
  8. package/skills/consumer-goods-promotion-bo-api-deploy/assets/set-comment-value/SetCommentValue.cls-meta.xml +5 -0
  9. package/skills/consumer-goods-promotion-bo-api-deploy/assets/set-comment-value/interview-answers.json +13 -0
  10. package/skills/consumer-goods-promotion-bo-api-deploy/assets/set-comment-value/payloads/copy.json +10 -0
  11. package/skills/consumer-goods-promotion-bo-api-deploy/assets/set-comment-value/payloads/create.json +20 -0
  12. package/skills/consumer-goods-promotion-bo-api-deploy/assets/set-comment-value/payloads/update.json +16 -0
  13. package/skills/consumer-goods-promotion-bo-api-deploy/references/conventions-and-payload-rules.md +273 -0
  14. package/skills/consumer-goods-promotion-bo-api-deploy/references/generate-and-wire.md +236 -0
  15. package/skills/consumer-goods-promotion-bo-api-deploy/references/reference-example-set-comment-value.md +132 -0
  16. package/skills/consumer-goods-promotion-bo-api-deploy/references/smoke-and-verify.md +211 -0
  17. package/skills/dx-code-analyzer-configure/scripts/validate-config.sh +14 -10
  18. package/skills/dx-code-analyzer-run/scripts/apply-fixes.js +45 -4
  19. package/skills/dx-code-analyzer-run/scripts/describe-rule.js +52 -32
  20. package/skills/dx-devops-project-manage/SKILL.md +197 -0
  21. package/skills/dx-devops-project-manage/examples/common-workflows.md +197 -0
  22. package/skills/dx-devops-project-manage/references/cli-commands.md +295 -0
  23. package/skills/dx-devops-project-manage/scripts/create-project.sh +48 -0
  24. package/skills/dx-devops-project-manage/scripts/list-projects.sh +51 -0
  25. package/skills/dx-devops-project-manage/scripts/update-project.sh +96 -0
  26. package/skills/education-cloud-academic-calendar-generate/SKILL.md +225 -0
  27. package/skills/education-cloud-academic-calendar-generate/examples/quarter-calendar.json +47 -0
  28. package/skills/education-cloud-academic-calendar-generate/examples/sample-output.md +57 -0
  29. package/skills/education-cloud-academic-calendar-generate/examples/semester-calendar.json +54 -0
  30. package/skills/education-cloud-academic-calendar-generate/references/calendar-systems.md +127 -0
  31. package/skills/education-cloud-academic-calendar-generate/references/date-validation.md +222 -0
  32. package/skills/education-cloud-academic-calendar-generate/references/foundation_prerequisites.md +40 -0
  33. package/skills/education-cloud-academic-calendar-generate/scripts/validate_calendar_dates.py +143 -0
  34. package/skills/education-cloud-course-catalog-migrate/SKILL.md +321 -0
  35. package/skills/education-cloud-course-catalog-migrate/references/gotchas-detail.md +16 -0
  36. package/skills/education-cloud-course-catalog-migrate/references/gotchas.md +16 -0
  37. package/skills/education-cloud-course-catalog-migrate/references/large-catalog-handling.md +42 -0
  38. package/skills/education-cloud-course-catalog-migrate/scripts/batch_courses.py +36 -0
  39. package/skills/education-cloud-course-catalog-migrate/scripts/detect_linked_courses.py +51 -0
  40. package/skills/education-cloud-course-catalog-migrate/scripts/detect_modality_variants.py +48 -0
  41. package/skills/education-cloud-course-catalog-migrate/scripts/resolve_api_version.py +43 -0
  42. package/skills/education-cloud-course-catalog-migrate/scripts/split_course_code.py +39 -0
  43. package/skills/education-cloud-course-catalog-migrate/scripts/validate_completeness.py +54 -0
  44. package/skills/education-cloud-multi-campus-configure/references/foundation_prerequisites.md +3 -5
  45. package/skills/education-cloud-student-recruitment-agent-configure/SKILL.md +177 -0
  46. package/skills/education-cloud-student-recruitment-agent-configure/references/agent-and-subagents.md +151 -0
  47. package/skills/education-cloud-student-recruitment-agent-configure/references/customer-narration.md +34 -0
  48. package/skills/education-cloud-student-recruitment-agent-configure/references/execution-model.md +54 -0
  49. package/skills/education-cloud-student-recruitment-agent-configure/references/flows.md +82 -0
  50. package/skills/education-cloud-student-recruitment-agent-configure/references/grounding.md +199 -0
  51. package/skills/education-cloud-student-recruitment-agent-configure/references/permissions.md +183 -0
  52. package/skills/education-cloud-student-recruitment-agent-configure/references/platform-enablement.md +82 -0
  53. package/skills/education-cloud-student-recruitment-agent-configure/references/prerequisites.md +158 -0
  54. package/skills/education-cloud-student-recruitment-agent-configure/references/routing.md +141 -0
  55. package/skills/experience-cms-brand-apply/SKILL.md +5 -5
  56. package/skills/experience-cms-brand-create/SKILL.md +2 -2
  57. package/skills/experience-cms-content-generate/SKILL.md +1 -0
  58. package/skills/experience-cms-content-render/SKILL.md +173 -0
  59. package/skills/experience-cms-content-render/assets/angular/DetailPage.component.ts +25 -0
  60. package/skills/experience-cms-content-render/assets/angular/MediaRenderer.component.ts +133 -0
  61. package/skills/experience-cms-content-render/assets/angular/TypeList.component.ts +38 -0
  62. package/skills/experience-cms-content-render/assets/angular/TypeRenderer.component.ts +90 -0
  63. package/skills/experience-cms-content-render/assets/angular/cms-content.component.ts +248 -0
  64. package/skills/experience-cms-content-render/assets/angular/cms-item.service.ts +100 -0
  65. package/skills/experience-cms-content-render/assets/react/DetailPage.tsx +20 -0
  66. package/skills/experience-cms-content-render/assets/react/MediaRenderer.tsx +129 -0
  67. package/skills/experience-cms-content-render/assets/react/TypeList.tsx +40 -0
  68. package/skills/experience-cms-content-render/assets/react/TypeRenderer.tsx +64 -0
  69. package/skills/experience-cms-content-render/assets/react/heuristicRenderer.tsx +310 -0
  70. package/skills/experience-cms-content-render/assets/react/useCmsItem.ts +129 -0
  71. package/skills/experience-cms-content-render/assets/shared/cmsContentType.ts +49 -0
  72. package/skills/experience-cms-content-render/assets/shared/cmsCore.types.ts +96 -0
  73. package/skills/experience-cms-content-render/assets/shared/externalRefs.ts +55 -0
  74. package/skills/experience-cms-content-render/references/bulk-loading.md +60 -0
  75. package/skills/experience-cms-content-render/references/codegen-guardrails.md +111 -0
  76. package/skills/experience-cms-content-render/references/detail-pages.md +87 -0
  77. package/skills/experience-cms-content-render/references/embed-recipes.md +127 -0
  78. package/skills/experience-cms-content-render/references/failure-modes.md +96 -0
  79. package/skills/experience-cms-content-render/references/heuristic-render-rules.md +131 -0
  80. package/skills/experience-cms-content-render/references/init-scaffold.md +122 -0
  81. package/skills/experience-cms-content-render/references/interaction-model.md +173 -0
  82. package/skills/experience-cms-content-render/references/package-api.md +106 -0
  83. package/skills/experience-cms-content-render/references/schema-sync.md +114 -0
  84. package/skills/experience-cms-content-render/references/styling-scopes.md +65 -0
  85. package/skills/experience-cms-content-render/references/verify.md +49 -0
  86. package/skills/experience-cms-content-type-generate/SKILL.md +2 -2
  87. package/skills/experience-content-media-stock-image-search/SKILL.md +5 -4
  88. package/skills/experience-search-coordinate/SKILL.md +198 -0
  89. package/skills/experience-search-coordinate/assets/search-payload-template.json +25 -0
  90. package/skills/experience-search-coordinate/references/content-route.md +313 -0
  91. package/skills/experience-search-coordinate/references/content-type-discovery.md +57 -0
  92. package/skills/experience-search-coordinate/references/media-route.md +172 -0
  93. package/skills/experience-search-coordinate/references/scope-resolution.md +14 -0
  94. package/skills/experience-ui-bundle-localize/SKILL.md +1 -1
  95. package/skills/experience-ui-bundle-localize/references/i18n-setup.md +5 -3
  96. package/skills/experience-ui-bundle-project-generate/SKILL.md +18 -14
  97. package/skills/experience-ui-bundle-project-generate/references/angular-project-generate.md +22 -0
  98. package/skills/experience-ui-bundle-project-generate/references/react-project-generate.md +20 -0
  99. package/skills/experience-ui-bundle-salesforce-data-access/SKILL.md +58 -54
  100. package/skills/experience-ui-bundle-salesforce-data-access/references/caching.md +6 -0
  101. package/skills/experience-ui-bundle-salesforce-data-access/references/graphiti-cli.md +2 -2
  102. package/skills/experience-ui-bundle-salesforce-data-access/references/migration.md +6 -0
  103. package/skills/experience-ui-bundle-salesforce-data-access/references/rest-and-integration.md +2 -1
  104. package/skills/experience-ui-bundle-salesforce-data-access/references/sdk-api.md +6 -0
  105. package/skills/experience-ui-bundle-site-generate/SKILL.md +59 -8
  106. package/skills/experience-ui-bundle-site-generate/references/configure-metadata-digital-experience.md +8 -3
  107. package/skills/experience-ui-bundle-site-generate/references/configure-metadata-language-settings.md +120 -0
  108. package/skills/life-sciences-fieldsalesrep-coordinate/SKILL.md +336 -0
  109. package/skills/life-sciences-fieldsalesrep-coordinate/references/orchestration-flow.md +143 -0
  110. package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-2-starter-config-application-flexipage-mapping.md +127 -0
  111. package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-2-starter-config-deploy-commands.md +116 -0
  112. package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-2-starter-config-lifesci-metadata-deploy.md +111 -0
  113. package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-2-starter-config-overview.md +312 -0
  114. package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-2-starter-config-profile-layout-assignments.md +171 -0
  115. package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-2-starter-config-state-tracking.md +64 -0
  116. package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-2-starter-config-trigger-handlers.md +122 -0
  117. package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-4-user-provisioning-overview.md +335 -0
  118. package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-4-user-provisioning-user-provisioning-details.md +140 -0
  119. package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-5-visit-creation-execution-state-and-recovery.md +196 -0
  120. package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-5-visit-creation-metadata-cache-generation.md +155 -0
  121. package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-5-visit-creation-overview.md +307 -0
  122. package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-5-visit-creation-visit-creation-data.md +211 -0
  123. package/skills/life-sciences-fieldsalesrep-coordinate/references/state-machine-and-changes.md +108 -0
  124. package/skills/life-sciences-kam-coordinate/SKILL.md +241 -0
  125. package/skills/life-sciences-kam-coordinate/references/orchestration-flow.md +152 -0
  126. package/skills/life-sciences-kam-coordinate/references/stage-2-starter-config-application-flexipage-mapping.md +79 -0
  127. package/skills/life-sciences-kam-coordinate/references/stage-2-starter-config-deploy-commands.md +131 -0
  128. package/skills/life-sciences-kam-coordinate/references/stage-2-starter-config-kam-config-records.md +85 -0
  129. package/skills/life-sciences-kam-coordinate/references/stage-2-starter-config-lifesci-metadata-deploy.md +112 -0
  130. package/skills/life-sciences-kam-coordinate/references/stage-2-starter-config-overview.md +202 -0
  131. package/skills/life-sciences-kam-coordinate/references/stage-2-starter-config-profile-layout-assignments.md +67 -0
  132. package/skills/life-sciences-kam-coordinate/references/stage-2-starter-config-state-tracking.md +65 -0
  133. package/skills/life-sciences-kam-coordinate/references/stage-2-starter-config-trigger-handlers.md +123 -0
  134. package/skills/life-sciences-kam-coordinate/references/stage-4-participant-role-and-sprint.md +89 -0
  135. package/skills/life-sciences-kam-coordinate/references/stage-5-data-and-plan-templates-overview.md +337 -0
  136. package/skills/life-sciences-kam-coordinate/references/stage-5-data-creation-data.md +248 -0
  137. package/skills/life-sciences-kam-coordinate/references/stage-6-ipad-validation-script.md +35 -0
  138. package/skills/life-sciences-kam-coordinate/references/stage-6-metadata-cache-generation.md +155 -0
  139. package/skills/life-sciences-kam-coordinate/references/stage-6-user-provisioning-details.md +146 -0
  140. package/skills/life-sciences-kam-coordinate/references/stage-6-user-provisioning-overview.md +89 -0
  141. package/skills/life-sciences-kam-coordinate/references/state-machine-and-changes.md +114 -0
  142. package/skills/life-sciences-prerequisites-validate/SKILL.md +138 -0
  143. package/skills/life-sciences-prerequisites-validate/references/checks-org-settings.md +190 -0
  144. package/skills/life-sciences-prerequisites-validate/references/checks-user-and-package.md +211 -0
  145. package/skills/life-sciences-territory-configure/SKILL.md +217 -0
  146. package/skills/life-sciences-territory-configure/references/territory-metadata.md +262 -0
  147. package/skills/platform-apex-logs-debug/SKILL.md +7 -7
  148. package/skills/platform-custom-application-generate/SKILL.md +4 -4
  149. package/skills/platform-custom-object-generate/SKILL.md +7 -7
  150. package/skills/platform-custom-tab-generate/SKILL.md +1 -1
  151. package/skills/platform-dsar-policy-manage/SKILL.md +272 -0
  152. package/skills/platform-dsar-policy-manage/references/configure.md +106 -0
  153. package/skills/platform-dsar-policy-manage/references/export-and-history.md +123 -0
  154. package/skills/platform-dsar-policy-manage/references/gap-analysis-guide.md +150 -0
  155. package/skills/platform-dsar-policy-manage/references/gap-scan.md +129 -0
  156. package/skills/platform-dsar-policy-manage/references/headless-sor.md +59 -0
  157. package/skills/platform-dsar-policy-manage/references/report-format.md +59 -0
  158. package/skills/platform-dsar-policy-manage/scripts/tests/__init__.py +0 -0
  159. package/skills/platform-dsar-policy-manage/scripts/tests/test_validate_policy_tree.py +76 -0
  160. package/skills/platform-dsar-policy-manage/scripts/validate-policy-tree.py +130 -0
  161. package/skills/platform-flexipage-generate/SKILL.md +4 -0
  162. package/skills/platform-list-view-generate/SKILL.md +1 -0
  163. package/skills/platform-salesforce-connect-adapter-generate/SKILL.md +359 -0
  164. package/skills/platform-salesforce-connect-adapter-generate/references/official-examples.md +69 -0
  165. package/skills/platform-salesforce-connect-adapter-generate/references/scenarios.md +187 -0
  166. package/skills/platform-soql-query/SKILL.md +8 -8
  167. package/skills/platform-value-set-generate/SKILL.md +2 -2
  168. package/skills/service-itsm-agentic-setup-cmdb-coordinate/SKILL.md +20 -27
  169. package/skills/service-native-voice-recording-transcription-configure/SKILL.md +47 -27
  170. package/skills/service-native-voice-recording-transcription-configure/references/thunderbird-voice-settings.md +13 -9
  171. package/skills/service-native-voice-recording-transcription-configure/scripts/enable-recording-transcription.sh +104 -45
@@ -0,0 +1,54 @@
1
+ #!/usr/bin/env python3
2
+ """Check a list of course records for missing required/recommended fields.
3
+
4
+ Reads a JSON array of course record objects from stdin. Prints a JSON report
5
+ of per-field present/missing counts and which records are missing which
6
+ fields. Works for both raw parsed data (before create) and org-record
7
+ read-backs (after create) — pass the field names present in that record shape.
8
+
9
+ Usage:
10
+ python3 scripts/validate_completeness.py --required Name,Duration --recommended Description,CourseType
11
+ """
12
+
13
+ from __future__ import annotations
14
+
15
+ import argparse
16
+ import json
17
+ import sys
18
+
19
+
20
+ def is_missing(value) -> bool:
21
+ return value is None or (isinstance(value, str) and value.strip() == "")
22
+
23
+
24
+ def check(records: list[dict], required: list[str], recommended: list[str]) -> dict:
25
+ report = {"total": len(records), "required": {}, "recommended": {}}
26
+ for label, fields in (("required", required), ("recommended", recommended)):
27
+ for field_name in fields:
28
+ missing_indexes = [i for i, r in enumerate(records) if is_missing(r.get(field_name))]
29
+ report[label][field_name] = {
30
+ "present": len(records) - len(missing_indexes),
31
+ "missing": len(missing_indexes),
32
+ "missing_indexes": missing_indexes,
33
+ }
34
+ return report
35
+
36
+
37
+ def main() -> int:
38
+ parser = argparse.ArgumentParser()
39
+ parser.add_argument("--required", default="", help="Comma-separated required field names")
40
+ parser.add_argument("--recommended", default="", help="Comma-separated recommended field names")
41
+ args = parser.parse_args()
42
+
43
+ records = json.load(sys.stdin)
44
+ required = [f for f in args.required.split(",") if f]
45
+ recommended = [f for f in args.recommended.split(",") if f]
46
+
47
+ report = check(records, required, recommended)
48
+ json.dump(report, sys.stdout, indent=2)
49
+ print()
50
+ return 0
51
+
52
+
53
+ if __name__ == "__main__":
54
+ sys.exit(main())
@@ -1,11 +1,9 @@
1
1
  # Step 0 — Foundation Prerequisites
2
2
 
3
3
  This skill can run standalone, without any other Education Cloud setup skill running first. Verify
4
- these before Step 1 — they are shared across the EDU skill family (also required by
5
- `education-cloud-domain-configure`, `education-cloud-academic-calendar-generate`,
6
- `education-cloud-course-catalog-migrate`). A gap here is a missing prerequisite to resolve, not a
7
- dead end — self-heal what's API-writable, ask/confirm before any write, otherwise instruct manual
8
- Setup and wait for confirmation.
4
+ these before Step 1 — they are shared across the EDU skill family. A gap here is a missing
5
+ prerequisite to resolve, not a dead end — self-heal what's API-writable, ask/confirm before any
6
+ write, otherwise instruct manual Setup and wait for confirmation.
9
7
 
10
8
  ## Checks (in order — each can stop the workflow if unresolved)
11
9
 
@@ -0,0 +1,177 @@
1
+ ---
2
+ name: education-cloud-student-recruitment-agent-configure
3
+ description: "Use this skill to set up and configure the Education Cloud Student Recruitment Agent (SRA) — the packaged Agentforce agent (namespace sturecruitment) that answers admissions FAQs, captures inquiries, registers campus tours, and files applications for prospective students. TRIGGER when the user wants to: create or configure an admissions, recruitment, or enrollment agent, set up the Student Recruitment Agent, deploy SRA to an Experience Cloud site, clone the SRA flows or permission sets, add the SRA subagents (Admissions and Enrollments FAQ; Admissions Application; Campus Tours, Visits, and Events Registration; Request for Information), wire Learning Program grounding, or build the escalation subagent. Guides platform enablement, permissions, grounding, agent creation, and channel deployment — API-first with UI fallback. DO NOT TRIGGER for the Transfer Credit Agent, generic Agentforce authoring (use agentforce-generate), or base Education Cloud domain enablement."
4
+ metadata:
5
+ version: "1.0"
6
+ minApiVersion: "67.0"
7
+ domains: ["Education"]
8
+ relatedSkills:
9
+ - "agentforce-generate"
10
+ - "platform-custom-field-generate"
11
+ - "platform-metadata-deploy"
12
+ - "platform-sharing-owd-configure"
13
+ - "platform-sharing-rules-generate"
14
+ # Runtime tier 1 is the headless `dispatch`/`dispatch_readonly` MCP tools.
15
+ # `sf` is the tier-2 fallback (MDAPI deploy + discovery/aggregate verifies) for
16
+ # runtimes that have a shell. See the three-tier ladder in `references/execution-model.md`.
17
+ cliTools:
18
+ - tool: ["sf"]
19
+ semver: ">=2.0.0"
20
+ accessCheck:
21
+ - type: "license"
22
+ value: "Agentforce"
23
+ - type: "orgPerm"
24
+ value: "EinsteinForEducationCloud"
25
+ ---
26
+
27
+ # Configuring the Education Cloud Student Recruitment Agent
28
+
29
+ ## Scope
30
+
31
+ - **In scope**: The full SRA setup sequence — the three platform toggles (Einstein, SRA, Omni-Channel; Agentforce provisioning is a verify-only Step-1 gate, not a toggle the skill flips), the `EducationCloudAiAgentAccess` permission set + OWD/sharing foundation, Learning Program grounding (Data Cloud data stream + hybrid search index + prompt template) and Knowledge/data-library grounding, creating the Service (unauth) and Employee (auth) agents, adding the 4 packaged SRA subagents, building the customer escalation subagent, cloning and configuring the 6 admissions flows (Service path), and deploying to Experience Cloud channels with user verification.
32
+ - **Out of scope**: The **Transfer Credit Agent** (separate agent, own perms/help — never include its steps); generic Agentforce agent authoring from scratch (see Cross-Skill Integration below); Data Cloud connector plumbing beyond the SRA grounding path; deciding the substance of Knowledge article content — Claude may draft an article for the customer to review, but the customer owns what it says.
33
+ - **The EDU foundation is a checked dependency, not an assumption**: SRA depends on base Education Cloud enablement, Person Accounts, R&A domain objects, and Data Cloud. This skill doesn't re-implement base Education Cloud domain enablement, but verifies each piece concretely (step 2a) and only surfaces a gap to the user to *fill what it detects*.
34
+
35
+ ---
36
+
37
+ ## Required Inputs
38
+
39
+ Gather or infer before starting:
40
+
41
+ - **Target org**: An Agentforce- and Education-Cloud-provisioned org with admin access — see Workflow step 1 for the gate.
42
+ - **Agent path(s)**: Unauthenticated (**Service** agent — the ASA, runs as the Einstein Agent User service account; no guest user), authenticated (**Employee** agent), or both.
43
+ - **Which subagents/topics** the customer wants live (default: all 4 packaged subagents + a custom escalation subagent).
44
+ - **Whether to add Create Inquiry to the Escalation subagent** (case-adjacent record creation on live-agent handoff) — ask if unspecified; the two outcomes are handoff-only, or handoff-plus-Create-Inquiry.
45
+
46
+ Defaults unless specified:
47
+ - Configure both agent paths if the org has both Service and Employee Agentforce licenses; otherwise the unauth/Service path only.
48
+ - Confirmation style: conversational, one-step-at-a-time — never autonomous. See *Talking to the user* below.
49
+
50
+ ---
51
+
52
+ ## How this skill runs — read first
53
+
54
+ **Step 0 resolves the org's current API version; Step 1 is a hard prerequisites gate — clear both before touching anything else.** The rest is a linear, sequential set of steps (0–13); confirm before every irreversible or org-shaping action, and end every step with its verify call. (See *Talking to the user* below.)
55
+
56
+ **Every org-changing step walks a three-tier ladder, then verifies — tier = what runtime you have:** **T1** headless MCP (`dispatch`/`dispatch_readonly`, no shell) · **T2** `sf` CLI (needs a shell) · **T3** Setup UI. Try T1; drop to T2 on a route/allowlist failure; T3 if no shell. Steps carry a best-tier tag; the verify-only preflight (step 1) uses STOP/ASK-USER labels instead. `references/execution-model.md` has the ladder detail — allowlist, route signals, query-routing, API-version policy; read it whenever a tier or route is unclear.
57
+
58
+ **Several steps land on T3 with no tier-1/tier-2 write path at all** (hand the user the Setup path, then verify) — each is tagged inline where it occurs (e.g. `[T3 · ...]` on steps 8, 9a, 12); every other action has a tier-1 path.
59
+
60
+ ---
61
+
62
+ ## Talking to the user — customer-facing narration (not optional)
63
+
64
+ **Mandatory, every run: read `references/customer-narration.md` in full before your first message to the customer — this is not background reading, it's the exact wording rules you follow at every step boundary for the entire session.** In short: the step numbers, tier tags (`T1`/`T2`/`T3`), and words like "gate," "the spine," or "per the doc" are internal authoring scaffolding — never say them to the customer, who has no idea this skill file exists. Lead every step boundary with the plain-language outcome, not the internal label; give a manual (UI) hand-off its complete concrete detail in the same message that asks the customer to go do it; and before every single create/update/delete, no matter how small, explain what it does and why in plain language, then wait for an explicit go-ahead — never on silence, never batched. `references/customer-narration.md` has the exact phrasing table and the do/don't examples — read it now.
65
+
66
+ ---
67
+
68
+ ## Workflow
69
+
70
+ All steps are sequential. Each step is one action + its best tier + a pointer to the reference that carries the exact calls, API names, and traps — read that reference before executing the step. Confirm before irreversible actions; end every step with its verify call.
71
+
72
+ ### 0 — Resolve the org's current API version
73
+
74
+ > **Do this first — before Step 1, before any other call in the run. Every `vXX` used in every step and reference file below comes from this resolution; never substitute a remembered or hardcoded version.** **CRITICAL: If this session has more than one Salesforce connection available, pin whichever one you use for this call as the org connection for the rest of the run — including after a context compaction.** A compacted summary can lose track of which connection was active; don't let that cause a switch to a different one partway through.
75
+
76
+ 0. **Resolve the current API version** [T1] — `dispatch_readonly({"url": "/services/data/", "method": "GET"})` on the org connection you're pinning for this run → take the **highest numeric `version`** from the returned array and reuse that literal, on that same connection, for every `vXX` call for the rest of this run. A stale/hardcoded version can make a real entity or feature absent from a schema-catalog read and misread as "the org doesn't have this." Full rationale and the per-surface version-floor exceptions: `references/execution-model.md`.
77
+
78
+ ### 1 — Verify prerequisites & gates
79
+
80
+ > **Step 1 is a hard gate — clear it before enabling or building anything.** If a STOP check (external grant the skill can't flip) or an ASK-USER check (foundation the skill doesn't own) fails, **do not start the toggles or the foundation build** — stop and request the grant, or have the user complete the missing Education Cloud foundation setup, then re-verify. **Also confirm now, before saying anything to the customer: `references/customer-narration.md` has been read in full this run (see *Talking to the user* above) — this gate isn't cleared until that's true too.** Don't build permissions/OWD/grounding for an agent that can't exist. Full preflight-gate table and every verify call: `references/prerequisites.md`.
81
+
82
+ 1. **Confirm edition & the Einstein-for-EDU license.** Both are STOP checks — halt if either is missing. (Agentforce provisioning is verified in item 2; Data Cloud in item 2a.)
83
+ 2. **Verify the three SRA gates** — Agentforce provisioning, Education Cloud enabled, and the runtime `orgHasStudentRecruitmentAgentBetaAccess` check (a three-part AND — its exact composition and per-part verify live in `references/prerequisites.md`). Stop if provisioning, the license, or the Gater is missing.
84
+ - **2a — Verify the EDU foundation** (don't assume base Education Cloud domain enablement has run): EDU enablement, Person Accounts, R&A domain schema, and Data Cloud. Ask the user to complete the first three, then re-verify; Data Cloud is a Home-Org grant (that's a STOP, not something the user can self-serve).
85
+
86
+ ### 2 — Enable the platform toggles
87
+
88
+ 3. **Enable the three platform toggles** [T1] — each has its own write path: Einstein Setup (`EinsteinGPTPlatformEnabled`), `RecruitmentAgentEnabled`, and Omni-Channel (`OmniChannelSettings` — required for channel deploy). → `references/platform-enablement.md`
89
+
90
+ ### 3 — Permissions & sharing foundation
91
+ → `references/permissions.md`
92
+
93
+ 4. **Clone + configure the persona permission sets, and assign the builder persona** [T1] — the OOTB `EducationCloudAiAgentAccess` is an empty shell, so clone it and customize its object/field matrix (assign the **clone**, never per-topic). **Assign the Admin/builder persona to the running user before cloning** — it grants the EDU field visibility the matrix build needs. **Auth/Employee path only:** also clone + configure `EducationCloudExprcCloudAccess` (Run Flows + object settings) for the community persona. The Einstein-user assignment is agent-dependent — Claude creates that user itself and grants it at **step 9**. The community-user assignment (and Enable Agent Access) is likewise agent-dependent → **step 10**.
94
+ 5. **Set OWD to Public Read Only on the 6 admissions objects** [T1 · one UI exception].
95
+ 6. **Do the topic-specific prep — 5 blocks** [T1 · two UI exceptions]: Campaign "Recruitment Event" picklist value + "Campus Tours" sharing rule, the Individual Application record type + its `ApplicationRecordTypeConfig`, and record-type→profile visibility.
96
+
97
+ ### 4 — Grounding (two independent mechanisms)
98
+ → `references/grounding.md`
99
+
100
+ 7. **Set up Knowledge grounding** [T1 · article authoring is human] — **check for existing Knowledge articles first and always ask the customer before drafting anything** (never auto-create — see `references/grounding.md` 7a), then create the Knowledge-sourced data library. Attaching it to the agent happens at **step 9** (a top-level AFScript field, wired into the same draft-only pass — no need to wait for the agent to be committed); the create itself needs no agent. Once wired, newly published articles are picked up automatically — no re-wire per article.
101
+ 8. **Wire Data Cloud grounding — 3 grounded objects, 2 search-index/retriever builds** (Learning Program; Academic Term shares the PTAT build) [T1 data spine · T3 index/retriever/prompt build].
102
+
103
+ ### 5 — Agent, subagents & flows
104
+
105
+ 9. **Create the agent(s) — headless, draft only** [T1] — fetch the real base template (Service: "Agentforce Service Agent", Employee: "Agentforce Employee Agent"), and in one combined pass: resolve `NEW_AGENT_USER` by creating the ASA's Einstein Agent User + granting it full perm/license parity (ASA only), strip the 7 default topics incl. the default Escalation topic (ASA only), author a handoff-only Escalation subagent (both paths — no Create Inquiry yet), and wire the step-7 knowledge library (both paths). Stop at `compile` — **do not `publish`**; UI fallback available at T3. → `references/agent-and-subagents.md`
106
+ - **If step 8's Data Cloud data spine was deferred while streams were still provisioning, check back on it now.** If it's still provisioning, check again at the end of each subsequent step (9a, 10, 11, 12) — it must be finished, including the T3 index/retriever/prompt-template build, before step 13's final verify. See `references/grounding.md` Mechanism 2 step 3.
107
+ - **9a — The customer's one Builder session** [T3 · Asset Library + Builder UI] — open the draft agent and: add the 4 packaged SRA subagents (Admissions and Enrollments FAQ; Admissions Application; Campus Tours, Visits, and Events Registration; Request for Information) from the Asset Library so the correct action `source`/`target` is set (not hand-authorable; watch for `TransferCreditEquivalency` in that list — Transfer Credit Agent's, not SRA's); delete the Create Admissions Application action (non-functional — confirm with the customer first); add Create Inquiry to the Escalation subagent via Builder's action picker per the Required Inputs choice, or skip it for handoff-only (left out at step 9 — its input mapping isn't safe to hand-author blind). Then **Save, then Commit Version — once**; nothing from step 9/9a is queryable before that. → `references/agent-and-subagents.md`
108
+ 10. **AEA/Employee-only: enable community access** [T1 write] — skip entirely on an ASA/Service-only build; the ASA path has nothing left here (topic cleanup, escalation authoring, knowledge, running-user grants all happen in step 9). Set **Enable Agent Access → the AEA agent** on the `SRA_Exprc_Cloud_Access` clone (built at step 4), then query existing community users and ask before assigning the clone + sibling PSs to them. → `references/agent-and-subagents.md` & `references/permissions.md`
109
+ 11. **Clone and configure the 6 admissions flows — unauthenticated/Service path only** [T1]. Two waves: clone + activate the wave-1 flows first — the 2 reusable subflows plus the 1 standalone flow (`GetPlnCampaigns`, which has no dependencies) — then clone the 3 consumers and re-point them at the active subflow clones. Skip entirely if building only the Employee agent. → `references/flows.md`
110
+
111
+ ### 6 — Deploy to channels & route
112
+ → `references/routing.md`
113
+
114
+ 12. **Deploy each agent to its channel + stand up Omni-Channel routing** [T1 routing objects · T3 messaging deployment & site] — read what exists first; front-load Experience Cloud site creation for any agent that doesn't already have one (the slowest part of this stack), then build the routing config → queue → inbound flow → channel stack while it provisions, then come back to the site to add the component and publish. One agent per channel = separate sites. **Auth/Employee path:** also enable user verification inline (two checkboxes, channel + site component; the unauthenticated/Service path gets neither).
115
+ 13. **Final structural verification** [verify] — run the queryable roll-up (agent active, all subagents present, flows active, channel + site up), then summarize which tier each step landed on and list anything left manual. **Finish here — do not wait on any manual action.** The conversational smoke test (messaging the agent so subagents respond, grounding answers, actions produce records) needs a live channel session that can't be driven headlessly; hand the user that short checklist to run themselves and don't poll for its results.
116
+
117
+ ---
118
+
119
+ ## Rules / Constraints
120
+
121
+ | Constraint | Rationale |
122
+ |-----------|-----------|
123
+ | Never promise a rollback you haven't confirmed | Reversibility differs per toggle — see `references/platform-enablement.md`; warn before any flip |
124
+ | Knowledge articles must be Published and contain no non-public data | The FAQ action is public; draft articles make the agent answer "no information" |
125
+ | Always confirm before *any* create/update/delete; run every step and its verify yourself — never delegate any part of this workflow to a separate helper process | See *Talking to the user* — the confirmation model depends on one continuous conversation; a delegated helper can prompt the customer on its own. polling isn't delegation |
126
+ | Do not deploy or push metadata packages | This skill configures a live org; package deployment belongs to a separate lifecycle skill |
127
+
128
+ ---
129
+
130
+ ## Gotchas
131
+
132
+ | Issue | Resolution |
133
+ |-------|------------|
134
+ | Org can't run SRA (agent endpoints 501 / `BotDefinition` not queryable, or `RecruitmentAgentEnabled` toggle absent/not-editable) | Preflight STOP check — catch at Step 1, not the Step-9 wall. Traces to one of three missing grants: Agentforce provisioning, the Einstein-for-EDU license, or the `StudentRecruitmentAgent256` Gater. Detect which and request it; don't retry lower tiers. See `references/prerequisites.md` |
135
+ | Messaging channel created headlessly but the agent isn't reachable at runtime | The channel record is tier 1, but the ESD cascade behind it is UI-only — hand the customer the UI deployment path in `references/routing.md` |
136
+ | Cloned consumer flows fail at runtime | Wave-2 consumers need subflow replacement + `DefaultUserOwnerId`, not just a clone — see `references/flows.md` |
137
+ | Subagent action target `compile`s clean but won't `publish` | `compile` is syntax-only and echoes back any target; only `validate`/`publish` check existence. Never hand-author targets — add subagents from the Asset Library so the correct `source`/`target` is injected. See `references/agent-and-subagents.md` |
138
+ | Only **Create Admissions Application** fails validate | The lone `api://` action; broken by a platform issue everywhere, not fixable from this org. Delete it at step 9a rather than working around it — every other action still publishes. See `references/agent-and-subagents.md` |
139
+ | Agent answers "no information" | Two causes: (1) Knowledge articles still Draft — publish them (tier-1 API-able), or (2) the data library isn't attached — check the AFScript's `knowledge.rag_feature_config_id` is `ARFPC_<libraryId>`, not empty. Check both |
140
+ | EDU objects (e.g. Academic Interest) show **0 fields** in Object Manager / the step-4 field-matrix build finds nothing | Ordering issue — the admin lacks the builder EDU-access sets. Assign **Education Cloud Full Access** + **Einstein for Education Cloud Access** first, before the field-matrix clone — fields are license-gated until then. See `references/permissions.md` |
141
+ | OWD or `ApplicationRecordTypeConfig` verify silently returns 0 rows | API-name traps: OWD's 6th object is **`ProgramTermApplnTimeline`** (truncated, not `...ApplicationTimeline`); perm-set uses `PreliminaryApplicationRef`. `RecordTypeName` takes the record type's **LABEL**, not DeveloperName/Id. See `references/permissions.md` |
142
+ | `/headless/metadata` returns `400 UNSUPPORTED_OPERATION` or `500 METADATA_CRUD_ERROR` | Drop to tier 2/3, don't retry — but first rule out a wrong-surface or missing-perm error, not an allowlist gap. See `references/execution-model.md`; the `setup/org/preferences` `ROUTE_NOT_FOUND` case: `references/platform-enablement.md` |
143
+ | `/query` returns `404` and looks like a platform outage | Check the call shape first — often self-inflicted: SOQL appended as `?q=...` instead of `queryParams: {"q": "<SOQL>"}`. A real outage is transient and all-versions-at-once. See `references/execution-model.md` |
144
+ | An earlier step genuinely needed `sf`/UI, and later steps keep using it too, out of habit | The tier ladder resets every step — re-attempt T1 first on each new action regardless of where the last step landed. See `references/execution-model.md` |
145
+
146
+ ---
147
+
148
+ ## Output Expectations
149
+
150
+ This skill configures a live org; no repository files. Expected outputs:
151
+
152
+ - Confirmation messages after each step (what was done, and at which tier — headless / `sf` CLI / manual UI).
153
+ - A **verify query result after every step** showing each toggle, perm set, flow, agent, subagent, and channel is in the expected state.
154
+ - A final summary listing which tier each step landed on, plus any items left pending on the T3-only steps.
155
+
156
+ ---
157
+
158
+ ## Cross-Skill Integration
159
+
160
+ | Need | Delegate to |
161
+ |------|-------------|
162
+ | Generic Agentforce agent authoring or metadata generation | `agentforce-generate` |
163
+
164
+ ---
165
+
166
+ ## Reference File Index
167
+
168
+ | File | When to read |
169
+ |------|-------------|
170
+ | `references/execution-model.md` | Any step — tier-ladder detail: allowlist, route signals, query-routing, API-version policy |
171
+ | `references/prerequisites.md` | Step 1 — edition/license check, the three SRA gates, EDU foundation verify |
172
+ | `references/platform-enablement.md` | Step 3 — per-toggle write paths |
173
+ | `references/permissions.md` | Steps 4–6, 9 & 10 — persona perm model, OWD list, topic-specific prep, agent-dependent grants |
174
+ | `references/grounding.md` | Steps 7–8 — Knowledge article/library flow, Data Cloud grounding builds |
175
+ | `references/agent-and-subagents.md` | Steps 9, 9a & 10 — agent creation, subagent + escalation wiring, the Builder session, AEA community grants |
176
+ | `references/flows.md` | Step 11 — flow inventory, 2-wave clone ordering |
177
+ | `references/routing.md` | Steps 12–13 — channel deploy, Omni-Channel routing, final structural verify |
@@ -0,0 +1,151 @@
1
+ # Agent creation & the 4 packaged subagents
2
+
3
+ Read at Workflow steps 9, 9a & 10. **Step 9** is Claude's single headless T1 pass that builds the agent bundle end-to-end and leaves it as an editable draft — template fetch, the ASA running-user creation + sentinel resolution + runtime grants, the ASA default-topic strip, the from-scratch Escalation subagent (handoff-only), and knowledge wiring, all before any `publish`. **Step 9a** is the customer's one Builder session — add the 4 packaged subagents, delete the broken Admissions Application action, add Create Inquiry to the Escalation subagent, then Save + Commit Version once (the one-and-only `validate`+`publish` for this agent). **Step 10** is AEA/Employee-only — the community-user access grants, which genuinely can't happen before the agent exists. Flow cloning (step 11, ASA-only) follows — it has no authoring dependency on the subagents, see `flows.md`.
4
+
5
+ ## Step 9 — Create the agent(s) [T1 — headless, draft only, no publish]
6
+
7
+ Agent creation does **not** require the Setup UI. The platform's own template catalog is headlessly readable, and a real running user for the ASA path can be minted headlessly too — so the entire agent can be built and left in a committable draft without ever opening Builder. This does **not** mean you can hand-author a bundle with no template backing it (see the packaged-subagent CRITICAL warnings below — those still apply).
8
+
9
+ **WARNING: Splice the fetched `agentScript` text directly — don't reach for a Python/code-execution tool to do it.** The captured template (point 1 below) is a large (~60KB+) but plain string; stripping the 7 default topic blocks (point 4) and inserting the new Escalation block (point 5) is ordinary text editing against that string, not a task that needs a scripting sandbox. A Python-execution tool may come from a separate, internal-only plugin (e.g. aisuite) that isn't guaranteed to be available in every environment this skill runs in — depending on it breaks the skill wherever it isn't installed.
10
+
11
+ 1. **Fetch the real template.** `GET /services/data/vXX/headless/invoke/platform/agent-authoring/get-agent-templates` → `200 {status_code:200, body:[{devName, namespace, name, agentType, agentScript, templateLabel, templateDescription, iconUrl}, ...]}`. Match by FQN `name` — `SvcCopilotTmpl__AgentforceServiceAgent` (Service) or `EmployeeCopilot__AgentforceEmployeeAgent` (Employee); both are served by this same catalog, not just industry-specific templates. Capture that entry's `agentScript` — the full AFScript body (~60KB+) — as the starting `resourceContent` for the new bundle.
12
+ 2. **ASA only — resolve the `NEW_AGENT_USER` sentinel with a real user, named so the customer can find it again later.** The fetched Service template's `access.default_agent_user` is the literal string `NEW_AGENT_USER` — Builder's "New User" toggle is what normally resolves this at creation time. Headlessly: create a real user matching Salesforce's own internal Digital Agent User pattern, but with an SRA-identifiable `Name`/`Username` rather than a generic hash — `POST /services/data/vXX/sobjects/User` body `{Name:"SRA Service Agent User", Username:"sra.service.agent.<hash>@salesforce.com", ProfileId:"<Einstein Agent User profile Id>", ...}` (Profile "Einstein Agent User", UserLicense "Einstein Agent", UserType Standard; `<hash>` keeps the username unique, it just no longer carries the whole label). Substitute that user's **Id** (not username) for the `NEW_AGENT_USER` string in `access.default_agent_user`. **CRITICAL: This naming choice matters beyond cosmetics — the customer has to pick this exact user back out of a dropdown at step 9a's Save** (see the CRITICAL warning under step 9a, point 4); a generic `DigitalAgent.<hash>` name is unrecognizable in that list, a named one isn't. The Employee template carries no `access:`/`default_agent_user` block at all — nothing to resolve on the AEA path, and no dedicated running user either (authenticated community users invoke the AEA agent as themselves).
13
+ 3. **ASA only — grant the running user its full permission-set/license parity, now, using the Id from step 2.** Because Claude minted this user directly, there's no need to wait for a post-commit `BotDefinition.BotUserId` query-back — assign the grants immediately, before the bundle is even created. **Assign the 6 PermissionSetLicenses before the 8 PermissionSetAssignments** — ordering matters here; see `permissions.md`'s three-persona table (Einstein Agent User row) for why and the complete grant list. **CRITICAL:** Without the full set, `publish` (or the customer's Commit Version) fails with a generic, sharing-flavored *"User doesn't have access to agent"* — that's actually a missing-license/permission-set problem, not a visibility one.
14
+ 4. **ASA only — strip the 7 default generic topics, in the same pass.** The **"Agentforce Service Agent"** template ships pre-populated with 7 generic non-SRA topics — Reservation Management, Service Customer Verification, Account Management, Case Management, Order Inquiries, Delivery Issues, and a pre-built generic Escalation topic — none of which belong on SRA. The **"Agentforce Employee Agent"** template does **not** carry these extras (Employee/AEA gets only the standard scaffolding — Agent Router, Off Topic, Ambiguous Question, General FAQ) — nothing to strip on that path. **Remove all 7 before the bundle is ever created**, then author a new, SRA-specific Escalation subagent from scratch (point 5, below) — the default Escalation topic stripped here is not reused, only its slot in the router. This agent is unauthenticated/guest-facing, and topics like Account Management or Case Management stay wired to real Salesforce actions by default — left in place, an anonymous guest could reach account/case data through them. Treat this as a data-exposure fix, not a scope trim. Delete each default topic's `subagent <Name>:` block and its `go_to_<Name>` entry under the router's `reasoning.actions` — a plain deletion, no new action target, so it doesn't need `validate` on its own.
15
+ 5. **Both paths — author the custom Escalation subagent, handoff-only, with no Create Inquiry action.** No packaged Escalation subagent exists (don't look for one in the Asset Library), so author the `subagent Escalation:` block by hand: `label`/`description`, `reasoning.instructions` with live-handoff language, and the router wiring (`go_to_Escalation: @utils.transition to @subagent.Escalation` under `start_agent agent_router:` → `reasoning.actions`). Don't add data-retrieval actions to it — that's the FAQ/Application/RFI subagents' job. Content to author:
16
+ - **Classification:** "Handles requests from users who want to escalate."
17
+ - **Scope:** help users who are stuck or want to escalate.
18
+ - **Activation:** trigger on phrases like "Help I'm stuck!", "I want to talk to a live person."
19
+ - **Instructions:** transfer-to-live-agent language, handled by reasoning/runtime with **no explicit transfer action def**.
20
+ - **CRITICAL: Deliberately leave the Create Inquiry action out of this pass** — see step 9a, point 3. Its target (`flow://eduadmissions__CreateInquiry`) is knowable and validate-able without the Asset Library (it's a managed flow that resolves whether or not it's been cloned yet — see step 11), but the action's full input-field mapping (first/last/email, request category, etc.) isn't something Claude can safely infer without discovery, and a wrong mapping produces an action that looks wired but silently mismaps or drops data. The customer adds it via Builder's guided action picker instead.
21
+ 6. **Both paths — wire knowledge.** Set the top-level `knowledge.rag_feature_config_id = "ARFPC_<libraryId>"` (+ `citations_enabled: true`) — agent-wide, not per-subagent, not a `featureAssignments` write (the library's `featureAssignments` stays `[]`). One field grounds every subagent's existing Answer-Questions-with-Knowledge action; see `grounding.md` (Mechanism 1) for the field shape.
22
+ 7. **Create the bundle and stop at compile — do not publish.** `POST .../nextgen-authoring/bundles` with the fully-edited `agentScript` inline as `resourceContent` → lands in `DRAFT` state (a brand-new bundle needs no separate draft/PATCH cycle — that's only for editing a bundle that already exists, see step 9a's NGA lifecycle below). `POST .../nextgen-authoring/afscript/compile` (passing the explicit `content` field, not just an Id — `bundleVersionId` alone fails consistently) to catch syntax errors. **Do not call `validate` or `publish` here.** A bundle left in pure DRAFT — never published via the API — is fully visible and editable in Builder (Explorer panel → Subagents → Add from Asset Library works against it), and the customer's own Commit Version in step 9a performs the one-and-only `validate` + `publish` for this agent. Calling `publish` here would mint a throwaway `BotVersion` before the customer's own step-9a edits land in the same version.
23
+ - **Fallback (T3)** if the template fetch or headless bundle-create isn't reachable in a given org: create the agent in Builder from the named template ("Agentforce Service Agent" / "Agentforce Employee Agent"), using the **New User** toggle on the Service agent's creation modal (Employee has no such toggle — authenticated users invoke it as themselves). Everything else in this step (grants, topic-strip, escalation authoring, knowledge wiring) still runs headlessly against that agent's bundle once it exists, via the NGA edit lifecycle below — it just costs an extra GET/draft/PATCH cycle instead of folding into the initial create.
24
+
25
+ **Metadata keys:**
26
+ - Agent template keys: `SvcCopilotTmpl__AgentforceServiceAgent` (Service) / `EmployeeCopilot__AgentforceEmployeeAgent` (Employee) — the stock base-Agentforce templates, served via `get-agent-templates`; **not** `sturecruitment__StudentRecruitment` — the SRA identity comes entirely from the packaged subagents added at step 9a, not from the base template's name.
27
+ - Gated by `OrgPermissions.EinsteinForEducationCloud`, `OrgPreferences.RecruitmentAgentEnabled`, `Gater.com.salesforce.StudentRecruitmentAgent256`.
28
+ - Topics gated `allowedAgentTypes: [EinsteinServiceAgent, AgentforceEmployeeAgent]` — one subagent set serves **both** agent types.
29
+ - Discrete `.genAiPlanner`/`.bot` file names are generated at creation time.
30
+ - Service vs Employee is distinguished by `BotDefinition.Type` (`Bot`/`InternalCopilot`/`ExternalCopilot`/`AgentforceOrchestrator`) + `AgentType`.
31
+
32
+ ## Step 9a — The customer's one Builder session: packaged subagents, cleanup & Create Inquiry [T3]
33
+
34
+ Everything here happens **after** step 9 has left the agent as an editable draft, and is intentionally the *only* point in the whole build where the customer touches Builder. **Open the agent from the Agentforce Studio app** — not Setup → Agents or "Agentforce Agents," a different destination that doesn't launch Builder — then open the draft agent (Agentforce Service Agent / Agentforce Employee Agent) and launch it in Agentforce Builder. It ends in exactly one Commit Version.
35
+
36
+ 1. **Add the 4 packaged subagents from the Asset Library** — Explorer panel → Subagents → the "+" ("Add or create subagent") → Add from Asset Library. This is never a "Topics panel," and there's no "New Topic" control to reach it through — the "+" next to Subagents is the only entry point. Expect a long, unfiltered list here — 20+ subagents from every package/agent installed in the org, not a short SRA-only set — so find each of the 4 real labels by name (see the table below) rather than assuming there's little to sort through. `TransferCreditEquivalency` is worth specifically watching for since it ships in the same `sturecruitment` package and can look like it belongs — but it's one distractor among many, not the only other item in the list; it's the Transfer Credit Agent's, never SRA's. This stays genuinely T3 (see the CRITICAL block below for why). **Use each subagent's real label when talking to the customer** — never shorthand like "FAQ," "Application," "Campus Tours," or "RFI."
37
+ 2. **Delete the Create Admissions Application action from the Admissions Application subagent.** It's currently non-functional — a platform issue blocks this action everywhere, unrelated to this org's setup. Deleting it doesn't touch the subagent's other actions (timeline/program/term lookups, FAQ answers).
38
+ 3. **Add Create Inquiry to the Escalation subagent, per the Required Inputs choice.** Claude authored the Escalation subagent handoff-only in step 9, deliberately leaving this action out (see step 9, point 5). In this same session, open the Escalation subagent's action list and add **Create Inquiry** (target `flow://eduadmissions__CreateInquiry`) through Builder's guided action picker, which handles the input-field mapping (first/last/email, request category) correctly — do this if Required Inputs captured a yes; skip this action entirely for handoff-only if it captured a no.
39
+ 4. **Only then Save, then Commit Version — once.** This is the single `validate` + `publish` for this agent. Nothing before this point is durable/queryable — a build that's only Saved has no `BotVersion`/`BotDefinition` row yet, and any tier-1 verify comes back empty even though the UI looks finished.
40
+ - **CRITICAL: ASA only — Save re-prompts for the running user; tell the customer to pick the existing one, never a new one.** Even though the running-user field already carries the real user's Id from step 9, point 2, clicking Save surfaces Builder's own picker for the agent's running user (worded along the lines of "New User" / "Existing User"). The customer must choose the **existing-user** option — e.g. a **"Select User"** control — and pick the user by its SRA-identifiable name (e.g. "SRA Service Agent User," set in step 9, point 2) from the dropdown. Accepting a "New User" default here mints a second Digital Agent User with none of step 9's permission-set/license grants — the agent then fails to publish, or publishes against the wrong, ungranted user. Skip this on the AEA/Employee path — it has no dedicated running user to reconfirm.
41
+
42
+ Confirm all four actions with the customer (subagents added, action deleted, Create Inquiry added or explicitly skipped, save/commit — including selecting the existing running user on the ASA path) before treating this step as done.
43
+
44
+ ### Mechanism — subagents live in the agent's Next-Gen Authoring (NGA) bundle AFScript
45
+
46
+ A subagent is **not** a standalone `GenAiPlugin` record you create separately — it is a `subagent <Name>:` block inside the agent's **NGA bundle AFScript** (`assets[].resourceContent`). Each block carries `label` / `description` / `reasoning.instructions` / `reasoning.actions` plus an `actions:` section defining every action's `source:` and `target:`. The router (`start_agent agent_router:`) transitions into each subagent via a `reasoning.actions` entry (`go_to_<Name>: @utils.transition to @subagent.<Name>`). This is the same mechanism step 9 uses to author the Escalation subagent and strip default topics — the only difference is step 9 folds its edits into the initial bundle-create body, while any *later* edit (e.g. re-touching an already-created bundle) goes through the GET/draft/PATCH cycle below.
47
+
48
+ **CRITICAL: The NGA edit lifecycle is tier-1, but the packaged-subagent *injection* is not.** The bundle-version GET/draft/PATCH/validate/publish cycle below runs at tier 1 — but it only *edits* an AFScript you already hold. It cannot supply the packaged targets: those come only from the Asset Library (a T3 builder action — see the CRITICAL block below). So **step 9a's "add the 4 packaged subagents" is T3** (Asset-Library-sourced); the tier-1 NGA lifecycle applies to editing a bundle you already hold (step 9's authoring pass, and any later re-edit). Don't read "NGA is T1" as "you can build the packaged subagents headlessly" — you can't.
49
+
50
+ **The NGA edit lifecycle — all tier 1 over `dispatch` (Connect API `next-gen-authoring`, v67.0+), for edits to a bundle that already exists:**
51
+
52
+ **WARNING: This path is keyed by the bundle-version Id (`1bZVW…`), NOT the BotVersion Id (`0X9VW…`).** They are distinct records — passing a BotVersion Id here 404s. Get the bundle-version Id from `GET .../nextgen-authoring/bundles` (list the agent's bundles → its current `bundleVersionId`).
53
+
54
+ **CRITICAL: Never PATCH a bundle version you haven't confirmed is a draft.** PATCHing an already-`PUBLISHED` bundle version returns `204` but is a **silent no-op** — no error, no write, no state change, no signal anything went wrong. Always create the draft (step 2 below) first and PATCH the resulting `draftBundleVersionId`, never the original.
55
+
56
+ **CRITICAL: Fully decode `resourceContent` before editing.** HTML-unescape it (repeat passes until no entities remain) before making any change. Resending still-entity-encoded text causes an undocumented, asymmetric double-encoding corruption — some entities double-encode, others don't. Decode once, edit the plain text, re-escape only for JSON-string transport in the PATCH body.
57
+
58
+ 1. `GET .../nextgen-authoring/bundle-versions/{bundleVersionId}` — get the current bundle version (its `assets[].resourceContent` is the AFScript).
59
+ 2. `POST .../nextgen-authoring/bundle-versions/{bundleVersionId}/draft` — create a draft (**non-destructive**; mints a `draftBundleVersionId`).
60
+ 3. `PATCH .../nextgen-authoring/bundle-versions/{draftId}` — write the edited `assets`. Compose the edited `resourceContent` directly as part of this request body in one pass — don't write the edit out separately and then re-transcribe it into the PATCH call. Strip read-only sibling fields (e.g. `compileResponse`) from the GET'd asset object before PATCHing it back, or the API 400s with `JSON_PARSER_ERROR`. There is **no partial-update variant** of this endpoint — every PATCH is a full-document replace regardless of edit size, so combine several edits to the same AFScript into **one** draft → one edit → one PATCH → one compile pass rather than a separate cycle per edit.
61
+ 4. `POST .../nextgen-authoring/afscript/compile` (syntax) **and/or** `POST .../nextgen-authoring/bundle-versions/{draftId}/validate` (existence). **Always pass the explicit `content` field alongside `bundleVersionId` on compile** — calling with `bundleVersionId` alone fails consistently (not transiently) with a generic, unhelpful error.
62
+ 5. `POST .../nextgen-authoring/bundle-versions/{draftId}/publish` — **DESTRUCTIVE: mints a Bot/BotVersion.** Only call this if you have a specific reason to publish outside the customer's own step-9a Commit Version (the normal path leaves this to them). **CRITICAL: If `validate`/`publish` 500s (`UNKNOWN_EXCEPTION`), don't retry it repeatedly** — try once or twice to rule out a blip, then stop and ask the customer to open the agent in Builder and click **Commit Version**, which re-runs validate/publish server-side and succeeds through outage windows that reject the headless call.
63
+
64
+ **CRITICAL: compile ≠ validate — never trust compile as proof an action reference is real.** `compile` is **syntactic only** (it also catches internal self-consistency — e.g. a `reasoning.actions` reference with no matching `actions:` definition — but not whether a target actually exists): it accepts any well-formed AFScript and echoes back `source`/`target` even when the target doesn't exist. `validate` is the **authoritative existence check** against the action registry. Always `validate` (or publish) before trusting a reference whenever an edit adds or changes an action target. For a pure-deletion edit that adds/changes no target (e.g. step 9's topic-strip), there's nothing new for validate to check — compile alone is sufficient.
65
+
66
+ ### CRITICAL: Add subagents from the Asset Library — do NOT hand-author the action targets
67
+
68
+ Adding a packaged subagent from the **Agentforce Asset Library** is **mandatory, not a style preference** — but reach it *from inside the agent*, not a separate Setup destination: open the agent in **Agentforce Builder → Explorer panel → Subagents → the "+" ("Add or create subagent") → Add from Asset Library**. The action `target` is the *underlying invocable resource URI* (a managed flow, prompt template, or standard action) and does **not** derive from the action's `source` name — e.g. source `sturecruitment__CreateCampusTourRegistration` → target `flow://eduadmissions__CreateCampusTourRgstr` (**different namespace AND different API name**). There is **no guessable transform**; only the Asset Library supplies the correct mapping for a first build, and a hand-authored target passes `compile` but fails `validate`.
69
+
70
+ **CRITICAL: You cannot read the target map to bootstrap a fresh org.** The `GenAiPluginDefinition` (subagent) and `GenAiFunctionDefinition` (action `source`/`InvocationTarget`/`InvocationTargetType`) records are **per-agent-version copies minted when a subagent is added to an agent** — their `DeveloperName`s are suffixed with the parent `GenAiPlannerDefinition` Id (e.g. `AdmissionsApplication_16jVW000000QkNN`). On a fresh org that has not yet added the SRA subagents, these queries return **0 rows** — there is nothing to read, because the mapping doesn't exist until the Asset Library puts it there. The read surface is therefore a **verify-/read-back capability** for an org that already has the subagents (see Verify below), **not** a way to discover targets before the first add. The initial injection must come from the Asset Library.
71
+
72
+ Adding from the library edits the AFScript in exactly **two** places, and the router auto-wires — no separate wiring step: (a) inserts the `subagent <Name>:` block (with its `reasoning.actions` + `actions:` `source`/`target`/`inputs`/`outputs`), and (b) adds `go_to_<Name>: @utils.transition to @subagent.<Name>` under `start_agent agent_router:` → `reasoning.actions`.
73
+
74
+ ### The complete action→target map (4 packaged subagents + custom escalation)
75
+
76
+ Four target **schemes** are in play — this is the taxonomy to expect when reading back the AFScript:
77
+
78
+ | Subagent | Action (`source`) | `target` | Scheme |
79
+ |---|---|---|---|
80
+ | CampusTourVstAndEvntRgstr | `sturecruitment__CreateCampusTourRegistration` | `flow://eduadmissions__CreateCampusTourRgstr` | flow |
81
+ | CampusTourVstAndEvntRgstr | `sturecruitment__GetCampusTourCampaigns` | `flow://eduadmissions__GetPlnCampaigns` | flow |
82
+ | AdmissionsAndEnrollmentsFaq | `sturecruitment__GetLearningProgramData` | `generatePromptResponse://sturecruitment__getLearningPrograms` | prompt-template |
83
+ | AdmissionsAndEnrollmentsFaq | `sturecruitment__GetAcademicTermData` | `generatePromptResponse://sturecruitment__getAcademicTerms` | prompt-template |
84
+ | AdmissionsAndEnrollmentsFaq | `sturecruitment__GetApplicationTimelineData` | `generatePromptResponse://sturecruitment__getApplicationTimelines` | prompt-template |
85
+ | AdmissionsAndEnrollmentsFaq | `EmployeeCopilot__AnswerQuestionsWithKnowledge` | `standardInvocableAction://streamKnowledgeSearch` | standard |
86
+ | AdmissionsApplication | `sturecruitment__CreateAdmissionsApplication` | `api://Industries-Education.postPreliminaryApplicationReferences` | **api (Connect REST) — currently non-functional; delete right after adding this subagent (step 9a), see below** |
87
+ | AdmissionsApplication | `sturecruitment__GetProgramTermApplicationTimelineData` | `standardInvocableAction://getProgramTermApplTimelineData` | standard |
88
+ | AdmissionsApplication | `sturecruitment__GetAcademicTermData` | `generatePromptResponse://sturecruitment__getAcademicTerms` | prompt-template |
89
+ | AdmissionsApplication | `sturecruitment__GetLearningProgramData` | `generatePromptResponse://sturecruitment__getLearningPrograms` | prompt-template |
90
+ | AdmissionsApplication | `EmployeeCopilot__AnswerQuestionsWithKnowledge` | `standardInvocableAction://streamKnowledgeSearch` | standard |
91
+ | RequestForInformation | `sturecruitment__CreateAcademicInterest` | `flow://eduadmissions__ProcessAcademicInterest` | flow |
92
+ | RequestForInformation | `sturecruitment__GetAcademicTermData` | `generatePromptResponse://sturecruitment__getAcademicTerms` | prompt-template |
93
+ | RequestForInformation | `sturecruitment__GetLearningProgramData` | `generatePromptResponse://sturecruitment__getLearningPrograms` | prompt-template |
94
+ | Escalation (custom, authored step 9, action added by customer step 9a) | `sturecruitment__CreateInquiry` | `flow://eduadmissions__CreateInquiry` | flow — target is validate-able without the Asset Library (see step 9, point 5), but the customer adds the action itself via Builder's action picker |
95
+
96
+ Note two subtleties in the table: (1) the FAQ `Get…Data` actions are `generatePromptResponse://` **prompt-template** invocations — the concrete Step 8 grounding tie-in; (2) `AnswerQuestionsWithKnowledge` is `EmployeeCopilot__`-namespaced (the base-template knowledge action), not `sturecruitment__` — a subagent mixes base-template and packaged actions. The FAQ subagent's `GetApplicationTimelineData` (prompt-template) is a **different action** from the Application subagent's `GetProgramTermApplicationTimelineData` (`standardInvocableAction://getProgramTermApplTimelineData`) — keep them distinct despite the similar names.
97
+
98
+ ### The Admissions Application `api://` action — currently broken; delete it at step 9a
99
+
100
+ `CreateAdmissionsApplication` is the **only `api://`-scheme action** across all four subagents (it posts to the Admissions "Preliminary Application References" Connect endpoint, not a flow). Its target `api://Industries-Education.postPreliminaryApplicationReferences` is currently blocked by a platform-level issue affecting this action everywhere — not a license, user-permission, or recruitment-toggle problem, and not specific to this org. If `validate`/`publish` rejects only this one action with *"Invocable action 'Industries-Education.postPreliminaryApplicationReferences' does not exist"* while every other action still validates, that's this issue, not a misconfiguration on your side.
101
+
102
+ **The fix at this stage is to delete the action, not to chase the registration or build a workaround** — see the deletion step under step 9a above. Don't spend time re-registering it, re-adding it a different way, or wrapping it in Apex. Delete it and move on — the rest of the AdmissionsApplication subagent (timeline/program/term lookups, FAQ answers) is unaffected.
103
+
104
+ **Three failure modes for a subagent action target — diagnose in this order:**
105
+ 1. **Wrong string** (compile passes, validate fails) → you hand-authored it; re-add the subagent from the Asset Library.
106
+ 2. **Correct string, unregistered agent action** (validate fails "does not exist" though the underlying resource is live) → for `Industries-Education.postPreliminaryApplicationReferences` specifically, this is the known issue above — delete it (step 9a). For any other `api://` action showing this pattern, treat it as a genuine provisioning gap and escalate to the feature owner.
107
+ 3. **Correct string, registered** → validates and publishes.
108
+
109
+ ### The 4 packaged subagents
110
+
111
+ Add these from the **asset library**:
112
+
113
+ | Subagent (label) | `GenAiPluginDefinition` dev name | Key actions |
114
+ |---|---|---|
115
+ | Admissions and Enrollments FAQ | `sturecruitment__AdmissionsAndEnrollmentsFaq` | AnswerQuestionsWithKnowledge, GetLearningProgramData, GetAcademicTermData, GetApplicationTimelineData |
116
+ | Admissions Application | `sturecruitment__AdmissionsApplication` | CreateAdmissionsApplication, GetAcademicTermData, GetLearningProgramData, GetProgramTermApplicationTimelineData, AnswerQuestionsWithKnowledge |
117
+ | Campus Tours, Visits, and Events Registration | `sturecruitment__CampusTourVstAndEvntRgstr` | CreateCampusTourRegistration, GetCampusTourCampaigns |
118
+ | Request for Information | `sturecruitment__RequestForInformation` | CreateAcademicInterest, GetAcademicTermData, GetLearningProgramData |
119
+
120
+ > **Do NOT include `TransferCreditEquivalency`.** That YAML in the `sturecruitment` package belongs to the separate Transfer Credit Agent (own `TransferCreditEquivalencyAccess` perm, own help) — it is not part of SRA. It's easy to miss among the Asset Library's other entries (see step 9a, point 1, on why that list is long) since it ships in the very same package as the real 4.
121
+
122
+ ### Retrieval-action grounding note (ties step 9a to step 8)
123
+
124
+ - The FAQ, Application, and RFI subagents' **`Get … Data` retrieval actions are backed by prompt templates + retrievers** wired in step 8 (`grounding.md`). Only **3 base-SRA prompt templates** exist: `getLearningPrograms`, `getAcademicTerms`, and `getApplicationTimelines`. **WARNING: `getApplicationTimelines` grounds the PTAT entity** (DMO `ssot__ProgramTermApplicationTimeline__dlm`), NOT `ApplicationTimeline` — the "Application Timeline" display name is misleading; `grounding.md`'s Mechanism 2 table (row 3) owns this. So the FAQ subagent's retriever-backed `GetApplicationTimelineData` (this template) is PTAT-grounded, and is a **different action** from the Application subagent's deterministic `GetProgramTermApplicationTimelineData` invocable (next bullet) — both touch PTAT but via different mechanisms. Do NOT expect (or wire) the 2 Transfer-Credit-Agent templates — they belong to a separate agent (see the TransferCreditEquivalency exclusion above).
125
+ - **CRITICAL: `GetProgramTermApplicationTimelineData` stays a STANDARD_INVOCABLE action** (deterministic — it invokes the packaged flow/apex, not a free-form retriever). Do not convert it to a generated retriever action; its grounding (PTAT DMO) is set up in step 8 but the *action* type is fixed.
126
+
127
+ ## Step 10 — AEA/Employee-only: enable community access [T1 write]
128
+
129
+ Step 10 covers only the AEA/Employee path's community-user access. The ASA/Service path has nothing left here — topic cleanup, escalation authoring, knowledge wiring, and running-user grants all happen in **step 9**. Skip this step entirely on an ASA-only build.
130
+
131
+ - The `SRA_Exprc_Cloud_Access` clone (built + configured at Step 4 — Run Flows + object settings, no agent required — see `permissions.md`) needs **Enable Agent Access → the AEA agent** set on it. By step 10 the AEA agent is already committed — step 9a's Commit Version precedes this step — so it's selectable against a real `BotDefinition`, not a draft.
132
+ - **Then query community users and ask before assigning** — community users are independent of the Experience Cloud site, so don't defer to Step 12. Read existing community users (profiles `Customer Community Plus User` / `Customer Community User`) at tier 1, then ask, e.g. *"I see you have N community users — want me to turn on agent access for them now? If not, you'll need to grant them access later so they can reach the agent."* Per the customer's answer, assign the clone + the sibling PSs (Prompt Template User, Knowledge, Data Cloud starter) to those users (`DUPLICATE_VALUE` on an existing assignment is benign).
133
+
134
+ ## Verify (attempt T1 `/query`/`/tooling/query` → `sf` fallback)
135
+
136
+ Agent/subagent creation is provisioning-gated (the org must be Agentforce-provisioned — a step-1 verify, not this step's concern), but the result is verifiable at **tier 1**. Run the three SOQL projections below at tier 1 — the agent read over `/services/data/vXX/query` and the subagent + action-target reads over `/services/data/vXX/tooling/query/`, all `dispatch_readonly` — and fall back to the identical `sf` forms only if tier 1 is unavailable.
137
+
138
+ 1. **Agent exists, is active, and has a running user** — `SELECT Id, DeveloperName, MasterLabel, Type, BotUserId FROM BotDefinition WHERE DeveloperName LIKE '%Recruit%' OR DeveloperName LIKE '%StudentRecruitment%'`. For the **ASA/Service agent**, `BotUserId` should be the exact user created and granted in step 9 — a **null** `BotUserId` means the sentinel substitution was skipped — treat it as a build error to fix, not an expected state.
139
+ 2. **Subagents present** (packaged + custom escalation) — `SELECT DeveloperName, MasterLabel FROM GenAiPluginDefinition` on the **tooling** query surface. **WARNING: Query `GenAiPluginDefinition`, not `GenAiPlugin`** — see `execution-model.md`'s query-routing nuance (a) for why. `GenAiPluginDefinition` is the child of `GenAiPlannerDefinition` via `ParentId`; `GenAiPlannerDefinition` is also tooling-queryable for the planner read-back. Each subagent's `DeveloperName` is **suffixed with its parent planner Id** (e.g. `AdmissionsApplication_16jVW000000QkNN`), because these rows are per-agent-version copies minted at add-time — so match the suffix to the target agent's `GenAiPlannerDefinition` Id to confirm the subagents landed on the *right* agent.
140
+ 3. **Action targets landed correctly** (strong verify — asserts the full source→target map, not just presence) — `SELECT DeveloperName, PluginId, InvocationTarget, InvocationTargetType FROM GenAiFunctionDefinition` on the **tooling** surface. `PluginId` FKs back to the `GenAiPluginDefinition` subagent; `InvocationTarget` + `InvocationTargetType` give each action's resolved target (e.g. `CreateCampusTourRegistration` → `eduadmissions__CreateCampusTourRgstr`, type `flow`). Join to step 9a's action→target table to confirm every action resolved to the expected target. This is the authoritative post-add read; it returns **0 rows on an org that hasn't added the subagents yet** (nothing to read — not an error).
141
+
142
+ ```bash
143
+ # Tier-2 fallback (same SOQL as the three tier-1 reads above):
144
+ sf data query -q "SELECT Id, DeveloperName, MasterLabel, Type, BotUserId FROM BotDefinition WHERE DeveloperName LIKE '%Recruit%' OR DeveloperName LIKE '%StudentRecruitment%'" --target-org <alias>
145
+ sf data query --use-tooling-api -q "SELECT DeveloperName, MasterLabel FROM GenAiPluginDefinition" --target-org <alias>
146
+ sf data query --use-tooling-api -q "SELECT DeveloperName, PluginId, InvocationTarget, InvocationTargetType FROM GenAiFunctionDefinition" --target-org <alias>
147
+ ```
148
+
149
+ Confirm the 4 packaged subagents are present, plus the custom escalation subagent (step 9). Confirm `CreateAdmissionsApplication` is **absent** from the AdmissionsApplication subagent's rows in call 3 — it should have been deleted at step 9a. If it's still there, the deletion didn't take (or was skipped) — delete it in Builder and re-commit before treating step 9a as done.
150
+
151
+ Conversational smoke test (step 13, user-run in the deployed channel — not headless): send an escalation phrase ("I want to talk to a live person") and confirm the Escalation subagent triggers handoff and, if Create Inquiry was added, produces the inquiry records (Case + Educational Info Request + Academic Interest).
@@ -0,0 +1,34 @@
1
+ # Customer-facing narration — exact wording rules
2
+
3
+ Read this before your very first message to the customer, and re-check it at every step boundary. The step/phase numbers, the tier tags (`[T1]`/`[T3]`), and internal words like "preflight gate," "hard gate," and "the spine" are **authoring scaffolding written for the AI running this skill. They are not customer vocabulary — never say them out loud, including in your very first message.** A customer asked to set up an agent; they don't track a numbered sequence or a tier ladder, and they have no idea this skill file exists.
4
+
5
+ **CRITICAL: Words and framings to never say out loud, no exceptions:** "tier," "T1"/"T2"/"T3," "gate," a bare step number ("Step 9," "9a"), or anything that names or alludes to the skill's own existence or your process of following it — "per the doc," "according to the reference file," "the skill says," "the setup notes flagged this," "before delegating the clone work," "per my instructions." State the plain action itself instead: say *"Let me check who owns this flow first"* — never *"Per the doc, I need to confirm the flow owner constant before delegating the clone work."* If a sentence names a source, a process step, or an internal label — under any name, not just these — cut that clause and keep only the outcome.
6
+
7
+ - **Say the outcome, never the reasoning or process behind it.** Don't hedge about "what some docs say" or use "despite X" framing if the skill's own content turns out to be wrong — that's a skill bug to report back, not something to narrate around. Don't narrate your own search or trial-and-error either — trying a candidate endpoint, discovering the right one, correcting a first attempt that failed, or explaining a shortcut you're taking over some other approach. **WRONG:** *"'shared-platform-mcp-context-connect-api' looks right — it returns current user identity."* **WRONG:** *"Good, adding SobjectType fixed it."* **WRONG:** *"Streams list is paginated and long — rather than page through it, I'll just attempt to create each stream directly."* **WRONG:** *"v67.0 again — retrying with the correct version."* Work it out silently and state only the result.
8
+ - **Open the run in plain language.** Your first message names what you're doing *for them* — e.g. **CORRECT:** *"First, let me confirm your org is ready to run the agent — I'll check a few prerequisites."* Do **not** open with the scaffolding: **WRONG:** *"Starting the preflight gate (Step 1)."* / **WRONG:** *"Now I'll start Step 1 — the hard preflight gate."*
9
+ - **Keep API element names, tier tags, and endpoints in the technical detail, not the headline.** **CORRECT:** *"Turning on Einstein."* — not **WRONG:** *"Setting `enableEinsteinGptPlatform = true` via a T1 `EinsteinGptSettings` PUT."* (Show the call when it helps; the line a customer reads is the feature and what it does for them.)
10
+ - **At every step boundary — not just the opening message — lead with the outcome, not the internal label.** **CORRECT:** *"Now I'll turn on the platform settings the agent needs."* — not **WRONG:** *"Step 2 — the T1 toggles."* The leak that actually happens in practice: at a step boundary, the model reads its own internal label (the number, the `[T1]`/`[T3]` tag, the bolded title) and repeats it as the "name" of what it's doing — e.g. saying "Step 8, tier 1" or "Step 9... from a generic Agentforce template." Use the phrase in the right column below instead, every time, regardless of what the step's internal heading says:
11
+
12
+ | Step | Say this instead of the internal label |
13
+ |---|---|
14
+ | 1 / 2 / 2a (prerequisites) | "Let me confirm your org is ready — checking a few prerequisites." |
15
+ | 3 (platform toggles) | "Turning on the platform settings the agent needs." |
16
+ | 4 (permission sets) | "Setting up the permissions and data access the agent needs." |
17
+ | 5 (OWD) | "Adjusting sharing settings on a few admissions objects." |
18
+ | 6 (topic-specific prep) | "A couple of small setup items for campus tours and applications." |
19
+ | 7 (Knowledge grounding) | "Checking your existing Knowledge articles and setting up search." |
20
+ | 8 (Data Cloud grounding) | "Connecting your program and term data so the agent can answer questions about them." |
21
+ | 9 (create agent) | "Creating the agent and setting up hand-off to a live person." |
22
+ | 9a (add subagents in Builder) | "Adding its specific skills." |
23
+ | 10 (AEA community access) | "Connecting your community members' access." |
24
+ | 11 (flows) | "Configuring the admissions workflows behind the scenes." |
25
+ | 12 (deploy to channel) | "Connecting the agent to your chat channel." |
26
+ | 13 (final verify) | "Double-checking everything is wired up correctly." |
27
+
28
+ - **The leak isn't only at step-open — closings and manual-item call-outs leak the same way.** Don't announce completion with the internal label (**WRONG:** *"Step 4 is complete"*) — describe the outcome (**CORRECT:** *"Your permissions and data access are set up."*). Same for the manual items collected for the closing summary: never list them by their internal label (**WRONG:** *"You'll still need to do 6b and 6e yourself"*) — name the actual action (**CORRECT:** *"Two things need a quick manual step in Setup: sharing the Campus Tours records, and making the new application record type visible on a few profiles."*). If you state a count before listing them, get the count by counting the rows you're about to list, not from a running mental tally — a stated count that drifts from the actual list reads as sloppy even when every item is individually correct.
29
+
30
+ - **Workflow gate, not a wording rule: before every single create/update/delete, no matter how small, explain in plain language what it does and why it matters to them, then stop and wait for an explicit go-ahead.** This is a real fork, not a rhetorical one: don't run the action on silence, don't treat "ok" to one action as blanket approval for the next one, and don't batch several changes behind one explanation. **Flag any manual (UI) step** the same way, and collect them for the closing summary.
31
+
32
+ - **A manual (UI) hand-off is the complete instruction for that build, not a preview of one.** When a step lands on T3, give the customer everything needed to do that specific screen correctly — every field, filter, and value the reference file lists for it — in the same message that asks them to go do it. Never a one-line summary ("pick the object, save") that relies on the customer separately asking for "more specific instructions" before the real configuration comes out — that's not a reliable trigger, and a customer who just follows the one-liner ends up misconfiguring the screen. If you're about to name several sub-builds in one message (e.g. "first we'll do X, then Y, then Z"), that overview can name the shape of the work, but don't let it substitute for handing over X's full detail before the customer goes and does X.
33
+
34
+ - **A deferred background wait gets its own plain-language explanation, not a silent jump to the next activity.** Whenever a step's own mechanics say to move on while something finishes in the background (data still syncing, an index still building) rather than sit and poll for it now, say so before switching to the next thing — plainly, no internal step numbers or mechanism names, and don't imply you're actively watching it in real time when you're really just deferring the check to a later point: e.g. **CORRECT:** *"That needs some time to finish processing on its own — I'll check back on it later rather than wait here."* Don't let the transition just happen with no acknowledgement (**WRONG:** closing out one activity and opening the next as if nothing is still pending) — the customer should never wonder whether something got skipped or forgotten.
@@ -0,0 +1,54 @@
1
+ # Execution model — the three-tier fallback ladder
2
+
3
+ Read this whenever a step's tier or a route/allowlist question is unclear. SKILL.md "How this skill runs" is the summary; this file is the full detail. Every org-changing step follows the **same ladder, in order**: try tier 1; on failure or when the type has no tier-1 path, drop to tier 2; if that runtime isn't available, tier 3. Always finish with a verify.
4
+
5
+ > **CRITICAL: The ladder resets at every step — a lower tier never becomes the new default.** Landing on tier 2 or tier 3 for one step (because that type has no tier-1 path, or a route failed) says nothing about the next step. Re-attempt tier 1 first on the very next org-changing action even if the previous one dropped to `sf` or the UI — don't keep reaching for `sf`/UI on later steps just because the last one needed it. A whole run landing mostly on tier 2/3 is a coincidence of which types were involved, never evidence tier 1 stopped being worth trying.
6
+
7
+ ## API version policy — always use the org's current version, full stop
8
+
9
+ **Every call in this skill uses the org's current API version — the highest the org supports — never a lower, hardcoded number.** `vXX` in these reference files is a placeholder for that current version, substituted fresh at call time; any concrete `vNN.0` you see elsewhere in these files is illustrative of a past example, never a value to actually send. The resolution itself happens once, at **Step 0** (`SKILL.md`), before anything else in the run — this section is the rationale for that action, not a second place to run it.
10
+
11
+ **Why it matters, beyond avoiding an error:** a stale/lower version doesn't just fail loudly — it can silently omit a real entity or feature from a schema-catalog read (absent from `EntityDefinition`, `INVALID_TYPE`, etc.), which reads as "doesn't exist in this org" when it's actually just not exposed below that version. Treat any such absence as a version question first, before concluding the org lacks the thing. There is no upper ceiling to work around.
12
+
13
+ Three surfaces have a documented **minimum** — a floor that a current-version call usually already clears, kept here to explain a failure on a very old/downgraded org, or on a surface where the resolved current version is genuinely below the floor:
14
+
15
+ | Surface | Minimum | Why |
16
+ |---|---|---|
17
+ | Next-Gen Authoring `/services/data/vXX/nextgen-authoring/*` (no `/connect/` segment) | v67.0+ | The NGA bundle surface lands at v67.0. |
18
+ | Flow verify `/query` (`FlowDefinitionView`) | v62.0+ | Minimum for the `IsActive`/`ApiName` projection. |
19
+ | Data Cloud Simple Start `/services/data/vXX/ssot/simple-start/*` (`sobject-recommendations`, `auto-map-dlos`) | v67.0+ | 404s (`NOT_FOUND`) below this version. |
20
+
21
+ > **WARNING: Never send `v67.0` or `v62.0` literally just because they appear in this table.** They're floors, not a version to default to. Resolve the org's current version first and use it — **unless the resolved current version is below the floor for the specific surface you're calling**, in which case use that surface's floor, not the resolved current version and not a value in between. Don't discover a floor by trial-and-error (retrying versions until one works) when it's already listed here.
22
+
23
+ > **WARNING: Two different failure signatures on `/ssot/simple-start/*` mean two different things — don't conflate them.** A gateway-level `ROUTE_NOT_FOUND` means the **wrong dispatcher** (a write sent on `dispatch_readonly` instead of `dispatch`) — never a version issue; resend on the write `dispatch`. An endpoint-level `404`/`NOT_FOUND` in the response body (dispatcher was already correct) means the call landed **below this surface's v67.0+ floor** — use the floor per the table above, not a retry at some other guessed version.
24
+
25
+ ## Tier 1 — Headless MCP dispatch
26
+
27
+ The *only* tier a hosted-MCP customer without a shell can use. Reads: `dispatch_readonly`. Writes: the write-enabled `dispatch`. Both are synchronous REST — never a raw token/`curl`.
28
+
29
+ - **Component & settings metadata CRUD → `POST/PUT/GET /services/data/vXX/headless/metadata`**, a **per-type-allowlisted** surface. The **verb determines the operation** (POST=create, PUT=update, GET=read). A type not on the allowlist returns **`400 UNSUPPORTED_OPERATION`** — that is the signal to drop to tier 2, not an error to retry.
30
+ - **On the `/headless/metadata` allowlist:** `PermissionSet`, `PermissionSetGroup`, `Profile` (CRUD); `IndustriesSettings`, `OmniChannelSettings`, `CustomPreferencePageSettings` (R,U — settings files; `OmniChannelSettings` PUT flips `<enableOmniChannel>`, fullName `OmniChannel`); `Group`, `Role`, `RestrictionRule`, `CustomPermission`, `SharingSet`, `ApiNamedQuery`, `UserAccessPolicy`, `AccountSettings`; **`CustomObject` (the OWD `sharingModel`) and `StandardValueSet` (the Campaign `Type` picklist) — both tier-1 via `/headless/metadata`**. **`RecordType` is tier-1 via a different surface** — `POST /tooling/sobjects/RecordType` (nested `{FullName,Metadata}`), not `/headless/metadata`. **Not on this allowlist:** `Flow`, sharing rules (`SharingCriteriaRule`/`SharingOwnerRule` — CREATE unsupported through ANY MDAPI path). **WARNING:** Off the `/headless/metadata` allowlist ≠ no tier-1 path: **flow clone/author/activate has its own tier-1 surface** — the `/flowbuilder/*` Connect REST endpoints (see `flows.md`); only a `Flow` *MDAPI async deploy* has no tier-1 route. **Sharing-rule CREATE genuinely has no tier-1 path** → tier 3 UI.
31
+ - Attempt an allowlisted type at tier 1; on `ROUTE_NOT_FOUND` or `500 METADATA_CRUD_ERROR`, drop to tier 2. A `500 METADATA_CRUD_ERROR` can also mean a missing perm precondition — `FileBasedMetadataCrud` **and** `Headless360HostedMcpServer` must both be granted.
32
+ - **WARNING: `OWD (CustomObject sharingModel)` has one exception:** `ActionPlanTemplate` is tier-3-UI-only; the other 5 objects deploy at tier 1. See `permissions.md` Step 5 for the per-object rule.
33
+ - **Other synchronous REST also routes over dispatch** (not just metadata): sObject REST (incl. `/composite/sobjects`), Connect REST, Tooling REST (read AND write-by-Id, e.g. `POST /tooling/sobjects/RecordType`, `POST /tooling/sobjects/ApplicationRecordTypeConfig`). Use these for perm-set clone + *assignment*, record-type create, article publishing, grounding wiring.
34
+ - **The async Metadata API deploy (`/services/data/vXX/metadata/deployRequest` + SOAP) is NOT routed over dispatch** — it returns `ROUTE_NOT_FOUND` at the gateway. There is no headless async-deploy escape hatch — that is exactly why the genuinely-off-allowlist types (`Flow`, sharing rules) need tier 2/3.
35
+ - **SOQL `/query` AND `/tooling/query` route over `dispatch_readonly` (tier 1)** — including existence / aggregate (`GROUP BY`) / WHERE-filter reads with no known Id. **Route each read to the most specific tool that answers it — this is not a linear failover, and `/query` is not a last resort:**
36
+ 1. **Schema questions** (does a RecordType/field/picklist exist, its values) → **`describe`** (`GET /sobjects/<Type>/describe`). The most reliable read surface and the direct answer for schema — first *when applicable*.
37
+ 2. **A specific record whose Id you already hold** (create response, known DurableId) → **GET by Id** (`/sobjects/<Type>/<id>`). Direct confirm of the persisted record.
38
+ 3. **Discovery / existence / WHERE-filter / aggregate reads with no known Id** → **`/query`** (tier 1 over `dispatch_readonly` — the normal, correct path for these), `sf data query` (tier 2) as fallback, UI last.
39
+ 4. **On a `/query` outage** (see caveat below) that blocks a discovery read → **ask the user to supply the Id, then GET by Id.** Degraded mode only, never a preference over `/query`.
40
+ - **WARNING: `/query` can hit transient outage windows** where the whole query family (`/query`, `/tooling/query`, `/queryAll`) 404s across **all** API versions for a period, then self-recovers. This is transient, NOT version-gated (it clears across all API versions at once) and NOT a permanent regression — do not treat `/query` as unreliable, just **never make a verify hard-depend on a SOQL filter succeeding**; keep the GET-by-Id / ask-user fallback ready.
41
+ - **WARNING: Before concluding it's an outage, check the call shape — on `/query` OR `/tooling/query`, and whether the error reads as a `404` or a `400 ROUTE_NOT_FOUND`.** Both surfaces, both error shapes, trace to the same self-inflicted **query-string encoding** bug: the SOQL got hand-appended as `?q=...` directly onto `url` (often with a stray trailing slash, e.g. `/tooling/query/?q=SELECT...`) instead of passed as a separate `queryParams` object — the gateway rejects that literal path before the query ever runs. Fix: `url: "/services/data/vXX/tooling/query"` (no trailing slash, no `?q=`) with `queryParams: {"q": "<SOQL>"}`. Retry with that shape before treating it as a real outage.
42
+ - Nuances: (a) `/tooling/query FROM GenAiPlugin` returns `INVALID_TYPE` (that type isn't exposed to the query surface — consistent, not intermittent) — query **`GenAiPluginDefinition`** instead; (b) tooling-only entities (`EntityDefinition`, `ApplicationRecordTypeConfig`) need `/tooling/query`, not data `/query`; (c) `RecordType.DeveloperName` needs **data** `/query` (tooling `/query` returns `400 INVALID_FIELD`); (d) `EntityDefinition` rejects `OR` disjunctions — use `IN (...)`. Read **by known record Id / DurableId** and sObject **GET by Id** also route. (sObject GET does not accept `?fields=` — the router treats it as an external-id path segment.)
43
+
44
+ ## Tier 2 — `sf` CLI (MDAPI deploy of local source)
45
+
46
+ Requires a **shell** — available to a customer who has the CLI configured, **not** to a pure hosted-MCP runtime. It is the **fallback** for the tier-1 writes above (OWD `sharingModel`, `RecordType`, Campaign `StandardValueSet`) when tier 1 isn't reachable. Use `sf project deploy start` (component metadata), `sf org assign permset`, and `sf data query` (verify fallback only — `/query` is tier-1-routable, see the read-routing ladder above; `sf data query` is the tier-2 fallback for a discovery read during a `/query` outage window). Generate-then-deploy prior art exists as sibling skills the reference files name: OWD via `platform-sharing-owd-configure`, record types + picklist scoping via `platform-custom-field-generate`.
47
+
48
+ **WARNING: Sharing-rule create is NOT a tier-2 escape** — it fails identically at `sf`-deploy as at tier 1, a genuine tier-3 UI gap. See `permissions.md` Step 6b for the exact error and why the sibling deploy skills can't help.
49
+
50
+ > **Grounding (Learning Program / Data Cloud) has no tier-2 path** — the async index/embedding build has no supported public API and can only be triggered from the Setup UI. Treat grounding as **tier-1 Connect-REST attempt → tier-3 UI**; do NOT present a tier-2 `sf`-deploy path. See `grounding.md` for the specific types and why.
51
+
52
+ ## Tier 3 — Manual Setup-UI steps
53
+
54
+ When neither runtime tier works, hand the user the exact Setup path, wait for confirmation, then run the verify (tier-1 read-by-Id if possible, else the tier-2 `sf` / UI check). Every step ends in a concrete verify so the agent confirms org state rather than assuming the human's UI action succeeded.