user-story-writing-for-salesforce
Use this skill when authoring INVEST-compliant Salesforce user stories from gathered requirements: shaping the As-A/I-Want/So-That stem, writing Given-When-Then acceptance criteria, sizing complexity (S/M/L/XL), splitting stories that are too large for a sprint, and emitting handoff metadata that names the next downstream agent. Trigger keywords: user story, INVEST, story splitting, story sizing, As-A I-Want So-That, story handoff, recommended_agents, backlog item shape. NOT for requirements elicitation or stakeholder interviews (use admin/requirements-gathering-for-sf). NOT for the Given-When-Then technique itself in depth (use admin/acceptance-criteria-given-when-then). NOT for UAT test case design (use admin/uat-test-case-design). NOT for backlog prioritization (use admin/moscow-prioritization-for-sf-backlog).
Best use case
user-story-writing-for-salesforce is best used when you need a repeatable AI agent workflow instead of a one-off prompt.
Use this skill when authoring INVEST-compliant Salesforce user stories from gathered requirements: shaping the As-A/I-Want/So-That stem, writing Given-When-Then acceptance criteria, sizing complexity (S/M/L/XL), splitting stories that are too large for a sprint, and emitting handoff metadata that names the next downstream agent. Trigger keywords: user story, INVEST, story splitting, story sizing, As-A I-Want So-That, story handoff, recommended_agents, backlog item shape. NOT for requirements elicitation or stakeholder interviews (use admin/requirements-gathering-for-sf). NOT for the Given-When-Then technique itself in depth (use admin/acceptance-criteria-given-when-then). NOT for UAT test case design (use admin/uat-test-case-design). NOT for backlog prioritization (use admin/moscow-prioritization-for-sf-backlog).
Teams using user-story-writing-for-salesforce should expect a more consistent output, faster repeated execution, less prompt rewriting.
When to use this skill
- You want a reusable workflow that can be run more than once with consistent structure.
When not to use this skill
- You only need a quick one-off answer and do not need a reusable workflow.
- You cannot install or maintain the underlying files, dependencies, or repository context.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/user-story-writing-for-salesforce/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How user-story-writing-for-salesforce Compares
| Feature / Agent | user-story-writing-for-salesforce | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
Use this skill when authoring INVEST-compliant Salesforce user stories from gathered requirements: shaping the As-A/I-Want/So-That stem, writing Given-When-Then acceptance criteria, sizing complexity (S/M/L/XL), splitting stories that are too large for a sprint, and emitting handoff metadata that names the next downstream agent. Trigger keywords: user story, INVEST, story splitting, story sizing, As-A I-Want So-That, story handoff, recommended_agents, backlog item shape. NOT for requirements elicitation or stakeholder interviews (use admin/requirements-gathering-for-sf). NOT for the Given-When-Then technique itself in depth (use admin/acceptance-criteria-given-when-then). NOT for UAT test case design (use admin/uat-test-case-design). NOT for backlog prioritization (use admin/moscow-prioritization-for-sf-backlog).
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
SKILL.md Source
# User Story Writing For Salesforce
This skill activates after requirements have been gathered and the BA must reshape raw business needs into INVEST-compliant Salesforce user stories that downstream admin/dev agents can pick up without re-asking the user. It owns the *shape* of a story (stem, acceptance criteria, sizing, splitting, handoff metadata) — not the elicitation upstream and not the UAT/build/prioritization downstream.
---
## Before Starting
Gather this context before drafting stories:
- **Has elicitation actually happened?** A story without a real persona, real workflow, and real business outcome is a stub. If the requirement is still vague, return to `admin/requirements-gathering-for-sf` before writing stories.
- **Who is the persona, in Salesforce terms?** "User" is not a persona. The persona must resolve to a profile, permission set, or role (e.g. *Inside Sales Rep with Sales User profile*). Stories without a Salesforce-grounded persona break sharing and FLS reasoning during build.
- **Is there an existing story or epic this overlaps?** Duplicate stories pollute the backlog, race for the same record, and waste sprint capacity. Search the existing backlog before drafting a new story.
- **What downstream agents are available in the chain?** The `recommended_agents[]` handoff field only works if you know which agents the org runs (e.g. `object-designer`, `flow-builder`, `lwc-builder`, `permission-set-architect`). If unknown, default to `["object-designer", "permission-set-architect"]` and flag in `notes`.
---
## Core Concepts
### The INVEST Checklist
Every story must pass INVEST before it leaves the BA's hands. Salesforce-specific reading:
- **I — Independent.** The story does not block on another incomplete story. Salesforce dependency hotspots: page layout depends on record type, validation rule depends on field, sharing rule depends on OWD. If the story has a hard dependency, list it in `dependencies[]` and consider whether it can be split or reordered.
- **N — Negotiable.** Implementation detail (Flow vs Apex, screen vs record-triggered) is *not* fixed in the story body. The story states the *what*, the build agent picks the *how*. A story that names "use a Record-Triggered Flow with a fast field update" is over-specified.
- **V — Valuable.** The `So That` must name a concrete business outcome (revenue, time saved, error reduced, compliance met). "So that the system works" or "so that data is captured" are not valuable.
- **E — Estimable.** The build team can size it. If complexity is unknowable because the persona, object, or trigger condition is missing, the story is not estimable and must go back to refinement.
- **S — Small.** Fits in a single sprint with capacity to spare. The complexity heuristic below makes this concrete.
- **T — Testable.** Acceptance criteria are boolean pass/fail. Each Given-When-Then must be runnable in a sandbox without interpretation.
### The As-A / I-Want / So-That Stem
The canonical Salesforce shape:
```
As a [Salesforce-grounded persona — profile, permission set, or role],
I want [observable capability tied to a specific object/feature area],
So that [business outcome — revenue, time, error, compliance].
```
Anti-patterns to reject on sight:
- "As a user, I want…" — no persona.
- "As an admin, I want to add a field…" — describes the *implementation*, not the user need.
- "I want the system to automatically…" — system actions are not user wants; reshape as the persona who benefits.
- "So that the system works correctly" — not a business value statement.
### Given-When-Then Acceptance Criteria
This skill uses Given-When-Then but does **not** teach it in depth (that's `admin/acceptance-criteria-given-when-then`). The minimum bar here:
- Every story has **at least one** Given-When-Then block.
- Each block is structured: `Given <context>`, `When <action>`, `Then <observable Salesforce outcome>`.
- Observable outcome = a UI element, field value, error message, record state, or notification — not a database write or class invocation.
- Cover **happy path + at least one sad path** (validation failure, permission denial, null/empty case).
### Complexity Sizing — S / M / L / XL
Use this heuristic when sizing — not story points, not Fibonacci, just a 4-bucket size that downstream agents can consume:
| Size | Heuristic | Typical example |
|---|---|---|
| **S** | Single object, single field/perm change, no automation, no UI work. | Add a required field; grant a permission set. |
| **M** | Single object with one declarative automation (validation rule, simple flow), or one record page tweak. | Auto-set a field via flow; restrict edit via VR. |
| **L** | Multi-object, multi-step flow, or 1 LWC; may touch sharing or page layouts; single integration touchpoint. | Lead-to-Opportunity conversion flow with related records. |
| **XL** | Spans multiple personas, multi-system integration, or requires Apex/LWC + sharing redesign. **An XL must be split** before it leaves refinement. | Quote-to-cash refactor; new approval routing across regions. |
XL stories are not committed — they are split. See the next section.
### Story Splitting Techniques
When a story is XL (or arguably L but unclear), apply one of these splits in order of preference:
1. **By workflow steps.** "Convert lead → create opportunity → notify rep" → 3 stories.
2. **By business rule.** "Approval required for discount > 10% AND deal > $100k" → 2 stories, one rule per story.
3. **By data variation.** "Works for Direct, Partner, and Channel deals" → 3 stories, one record type at a time.
4. **By persona.** "Reps see X; managers see Y; execs see Z" → 3 stories per persona.
5. **By happy path / sad path.** Ship the happy path first, then layer error/exception/edge stories.
Each child story still has to pass INVEST on its own. A split that produces children that can't be demoed independently is the wrong split.
### Handoff Metadata — The JSON Shape
Every story emits a handoff JSON. Downstream agents (`object-designer`, `flow-builder`, `lwc-builder`, `permission-set-architect`) read this to pick up work without re-asking the user:
```json
{
"story_id": "US-LEAD-042",
"title": "Auto-assign hot leads to inside sales queue",
"as_a": "Marketing Operations Specialist with the Marketing Ops profile",
"i_want": "incoming Leads with Score >= 80 to land in the Inside Sales queue automatically",
"so_that": "high-intent leads are followed up within the 5-minute SLA window",
"acceptance_criteria": [
"Given a Lead with Score >= 80, When it is created, Then OwnerId is set to the Inside Sales queue.",
"Given a Lead with Score < 80, When it is created, Then OwnerId remains the original creator.",
"Given a Lead update where Score crosses from 79 to 80, When saved, Then OwnerId reassigns to Inside Sales queue."
],
"complexity": "M",
"recommended_agents": ["flow-builder", "permission-set-architect"],
"recommended_skills": ["flow/record-triggered-flows", "admin/queue-design"],
"dependencies": ["US-LEAD-040 (Lead Score field exists)"],
"notes": "Confirm queue membership before flow build. No Apex required at this size."
}
```
Field rules:
- `recommended_agents[]` — **required, non-empty**. Names the next agent(s) in the chain. If unsure, default to `["object-designer"]` and flag in `notes`.
- `recommended_skills[]` — pointers into the SfSkills repo (e.g. `flow/record-triggered-flows`). Optional but strongly preferred.
- `dependencies[]` — story IDs or named prerequisites (field exists, queue exists, integration live).
- `complexity` — exactly one of `S | M | L | XL`. XL means *not committable* — split first.
---
## Common Patterns
### Pattern: Reshape a Vague Requirement Into a Story
**When to use:** A stakeholder has said "we need lead routing." That's an epic, not a story.
**How it works:**
1. Identify the persona — who actually performs (or benefits from) the work daily?
2. Identify the trigger — what record event or user action starts the workflow?
3. Identify the outcome — what observable state confirms it worked?
4. Draft the As-A / I-Want / So-That stem.
5. Add 3+ Given-When-Then criteria — happy + sad + edge.
6. Size with the S/M/L/XL heuristic; split if XL.
7. Emit the handoff JSON with `recommended_agents[]` populated.
**Why not skip steps:** A story with no Given-When-Then is a wish, not a backlog item. Build agents will refuse to pick it up.
### Pattern: Split an XL Story
**When to use:** Sizing came back XL, or the team can't agree on size (which usually means it's XL with hidden scope).
**How it works:**
1. Pick the split axis (workflow, rule, data, persona, happy/sad).
2. Draft each child story with its own stem + Given-When-Then.
3. Verify each child passes INVEST independently.
4. Order the children: happy path first, sad path last; high-value first when possible.
5. Add cross-references in `dependencies[]`.
6. Replace the parent story with a tracker/epic; do not commit it.
**Why not just commit the XL:** XL stories drag across sprints, block dependent work, and demo poorly. The split is the correctness step.
### Pattern: Emit Handoff JSON Alongside Markdown
**When to use:** Always. The markdown is for humans; the JSON is for the next agent.
**How it works:**
1. Write the story as markdown for backlog tools (Jira, ADO, GitHub Issues).
2. Below the markdown, emit the JSON block in a fenced code block.
3. Populate `recommended_agents[]` from the chain available in the org.
4. Validate the JSON with `scripts/check_invest.py` (this skill's checker) before finalizing.
---
## Decision Guidance
| Situation | Recommended Approach | Reason |
|---|---|---|
| Persona is "user" or "admin" | Reject and ask BA to ground in a Salesforce profile/perm set/role | Generic personas break sharing and FLS reasoning |
| Story body names Flow vs Apex | Reject — that's a build-time decision | Violates INVEST-Negotiable |
| Acceptance criteria test the UI ("the button is blue") | Rewrite to test behavior ("clicking Save creates the record") | UI is Salesforce's responsibility; ACs test outcomes |
| Story has only happy-path AC | Add at least one sad path before sizing | Half-tested stories regress in UAT |
| Story sizes to XL | Split before committing | XL is uncommittable by definition |
| Story depends on another in-flight story | Add to `dependencies[]`; consider reordering | Independent-I in INVEST |
| Story mixes "the user does X" and "the system does Y" | Split by action source | Mixing actors hides automation triggers |
| `recommended_agents[]` is unknown | Default to `["object-designer"]` and flag in `notes` | Empty handoff metadata breaks the chain |
---
## Recommended Workflow
Step-by-step instructions an AI agent or BA follows when this skill activates:
1. **Confirm prerequisites** — verify requirements were gathered (skill: `admin/requirements-gathering-for-sf`). If not, route there first.
2. **Draft the stem** — As-A (Salesforce-grounded persona), I-Want (observable capability), So-That (business outcome). Reject generic personas and "the system" wants.
3. **Author Given-When-Then ACs** — 1 happy path minimum, 1+ sad path, edge cases as applicable. Each AC must be boolean-testable in a sandbox.
4. **Size with S/M/L/XL** — apply the heuristic table. XL means not committable.
5. **Split if needed** — pick a split axis, draft child stories, verify each child passes INVEST independently.
6. **Emit handoff JSON** — populate `recommended_agents[]`, `recommended_skills[]`, `dependencies[]`, `complexity`, `notes`. Validate with `scripts/check_invest.py`.
7. **Run review checklist** — INVEST pass, persona grounded, AC count > 0, complexity present, handoff JSON valid.
---
## Review Checklist
- [ ] Every story has a Salesforce-grounded persona (profile / permission set / role) — not "user" or "admin"
- [ ] Every `So That` names a concrete business outcome (revenue, time, error, compliance)
- [ ] Every story has at least one Given-When-Then acceptance criterion
- [ ] At least one sad path AC is present per story
- [ ] No story body names a specific Flow type, Apex class, or LWC component (Negotiable)
- [ ] Complexity is exactly one of S / M / L / XL
- [ ] No story is committed at XL — XL is split first
- [ ] Handoff JSON is present, valid, and `recommended_agents[]` is non-empty
- [ ] Dependencies on other stories are explicit in `dependencies[]`
- [ ] Story word count is reasonable (under ~250 words for the body); if it isn't, split
---
## Salesforce-Specific Gotchas
1. **Page-layout and record-type chains** — A story to "show a new field on the layout" is not Independent if the field doesn't exist yet. The build order is field → layout → validation rule. Surface this in `dependencies[]` or split the parent.
2. **Sharing-rule stories that look small** — "Managers can see their team's Cases" sounds S, but if OWD is Public Read/Write, the answer is "they already can" and the real story is OWD tightening. Sizing without checking OWD produces wrong-sized stories.
3. **Persona drift between stem and AC** — Stem says "Sales Rep" but the AC tests "Sales Manager can approve." That's two stories; split by persona.
---
## Output Artifacts
| Artifact | Description |
|---|---|
| Story markdown | Human-readable As-A / I-Want / So-That + Given-When-Then ACs, sized S/M/L/XL |
| Handoff JSON | Machine-readable shape consumed by `object-designer`, `flow-builder`, `lwc-builder`, `permission-set-architect` |
| Split rationale | When an XL is split into children, a short note explaining the split axis chosen |
| INVEST self-check report | Output of `scripts/check_invest.py` confirming the story passes structural lints |
---
## Related Skills
- `admin/requirements-gathering-for-sf` — runs upstream; produces the raw needs this skill reshapes
- `admin/acceptance-criteria-given-when-then` — owns the GWT technique in depth; this skill only enforces presence
- `admin/uat-test-case-design` — runs downstream; turns ACs into UAT scripts after build
- `admin/moscow-prioritization-for-sf-backlog` — runs alongside; orders the stories this skill produces
- `agents/object-designer/AGENT.md`, `agents/flow-builder/AGENT.md`, `agents/lwc-builder/AGENT.md`, `agents/permission-set-architect/AGENT.md` — common downstream consumers of the handoff JSONRelated Skills
salesforce-shield-deployment
Roll out Shield (Platform Encryption + Event Monitoring + Field Audit Trail) end-to-end, sequencing feature enablement to avoid data lockout. NOT for Classic Encryption or general PE design.
guest-user-security
Use when hardening the Experience Cloud guest user profile, controlling unauthenticated access to records and Apex, or investigating data exposure through guest SOQL. Covers object permissions, sharing model enforcement for unauthenticated users, and Apex execution context. NOT for Experience Cloud site creation (use Experience Cloud skills) or for authenticated external user security (use security/experience-cloud-security).
guest-user-security-audit
Auditing the security posture of an Experience Cloud (Community) site's Guest User. Covers the post-Spring '21 secure-by-default lockdown (object permissions removed, sharing rule grants required for any access), the Guest User profile permissions to remove (View All Data, Modify All Data, Manage Users, etc.), guest sharing rules, the Run-As-Guest test, OWASP A01 (Broken Access Control) mapping, and the standard set of leakage vectors (Apex with `without sharing`, Aura / LWC `@AuraEnabled` methods, public-site Visualforce, REST endpoints under `/services/apexrest`). NOT for Experience Cloud authenticated user setup (see experience/experience-cloud-user-management), NOT for general Salesforce profile design (see admin/profile-permset-design).
ferpa-compliance-in-salesforce
Use this skill when implementing FERPA (Family Educational Rights and Privacy Act) compliance controls in Salesforce Education Cloud or Education Data Architecture (EDA): LearnerProfile FERPA boolean fields, directory information opt-out via FLS and Individual data privacy flags, ContactPointTypeConsent for parental and third-party disclosure, 45-day student records response window tracking, and consent workflow automation. Trigger keywords: FERPA, student records privacy, LearnerProfile, parental disclosure, directory information opt-out, education data privacy, student consent, education cloud compliance. NOT for GDPR/CCPA general data privacy (see gdpr-data-privacy skill), platform encryption at rest (see platform-encryption skill), or HIPAA health-data compliance.
api-only-user-hardening
Provision and harden integration (API-only) users: no UI login, IP restrictions, minimum permission set, session lifetime, and monitoring. NOT for human admin account hardening.
industries-cpq-vs-salesforce-cpq
Use this skill when comparing Industries CPQ (formerly Vlocity CPQ) with Salesforce CPQ (Revenue Cloud managed package) — covering feature parity, decision criteria, migration paths, and coexistence patterns. Trigger keywords: Vlocity CPQ, Industries CPQ, Salesforce CPQ comparison, Revenue Cloud migration, CPQ selection, which CPQ to use. NOT for implementing, configuring, or debugging either CPQ product.
tableau-salesforce-connector
Tableau ↔ Salesforce integration patterns: Tableau Salesforce connector, Tableau for Salesforce, CRM Analytics alternative, Data Cloud + Tableau, embedded Tableau dashboards. Choose between connector modes (live, extract, direct-to-Data-Cloud). NOT for CRM Analytics Studio (use crm-analytics-foundation). NOT for generic Tableau Server setup.
slack-salesforce-integration-setup
Use this skill when setting up or troubleshooting the Salesforce for Slack managed app — including connecting a Salesforce org to a Slack workspace, configuring the three-party admin handshake, linking Slack channels to Salesforce records, enabling record preview sharing, and managing org-level limits. Triggers on: Salesforce for Slack app not connecting, Slack org connection setup, Salesforce record sharing in Slack, Slack workspace admin approval, connecting Salesforce to Slack. NOT for building custom Slack apps or Slack bots (separate development platform), not for Slack Workflow Builder Salesforce connector (use slack-workflow-builder skill), not for Flow-based Slack messaging (use flow-for-slack skill).
salesforce-to-salesforce-integration
Use this skill to implement Salesforce-to-Salesforce integration patterns — covering the native S2S feature, API-based cross-org sync, Platform Event bridging, and Salesforce Connect Cross-Org adapter. Trigger keywords: Salesforce to Salesforce integration, cross-org data sharing, S2S feature, cross-org Platform Events, Salesforce Connect cross-org. NOT for multi-org strategy or architecture decisions (use architect/multi-org-strategy), single-org data sharing, or external (non-Salesforce) system integration.
salesforce-maps-setup
Use when configuring Salesforce Maps (formerly MapAnything) — territory planning, route optimization, live tracking, geo-grid visualizations, and check-in/check-out workflows for Sales or Service field reps not on Field Service. Covers package installation order (Maps + Maps Advanced + Maps Routing/Live Tracking add-ons), the MapsTerritoryPlan / MapsAdvancedRoute / MapsLayer object family, base-data syncs (Geocoding and Routing services), and integration with Sales and Service Cloud records. Triggers: 'Salesforce Maps setup', 'MapAnything migration', 'territory planning by polygon', 'route optimization for sales reps', 'live tracking field reps', 'plot accounts on a map', 'check-in to the closest account'. NOT for Field Service Lightning territory and scheduling (use admin/fsl-scheduling-optimization-design and data/fsl-territory-data-setup) — Maps and FSL are different products. NOT for Consumer Goods Cloud retail visit planning (use admin/consumer-goods-cloud-setup) — RoutePlan/Visit objects are CG-specific. NOT for Tableau / CRM Analytics geo charts.
salesforce-functions-replacement
Salesforce Functions is retired (EOL Jan 2025). This skill maps Functions workloads to replacements: Heroku (with Hyperforce), external containers, Apex (where viable), Agentforce Actions, external compute via Named Credentials. NOT for Lambda / Azure Functions tutorials. NOT for Apex @future replacement (use async-selection tree).
salesforce-data-pipeline-etl
Export large Salesforce datasets to a lakehouse via Bulk API 2.0, CDC streams, or Salesforce Data Pipelines. NOT for ad-hoc exports.