UNPKG

aiwg

Version:

Cognitive architecture for AI-augmented software development with structured memory, ensemble validation, and closed-loop correction. FAIR-aligned artifacts, 84% cost reduction via human-in-the-loop, standards adopted by 100+ organizations.

722 lines (539 loc) 29.4 kB
# User Story: Password Reset (Complete Example) ## Why This Example This is a complete, production-ready user story for a password reset feature in an e-commerce platform. It demonstrates: - Clear INVEST criteria adherence - Comprehensive acceptance criteria with Gherkin syntax - Security-appropriate requirements - Realistic task breakdown and estimation - Proper dependency and risk identification - Quality annotations explaining good practices This example can be copied and adapted for similar authentication/security features. --- ## Metadata - **ID**: `US-AUTH-005` - **Type**: Requirement Card (User Story) - **Status**: Ready (moved from Draft after refinement) - **Owner**: Product Owner (Sarah Chen) - **Contributors**: Security Auditor, UX Designer, Backend Engineer - **Reviewers**: Product Owner, Security Lead, Technical Lead - **Team**: Platform Authentication Team - **Stakeholders**: Security Team, Customer Support, Legal/Compliance - **Created**: 2026-01-10 - **Last Updated**: 2026-01-28 - **Priority**: High (security-critical feature, blocks regulatory compliance) - **Story Points**: 5 (team consensus after refinement) - **Sprint**: Sprint 12 (starting 2026-02-01) - **Related**: - Epic: `EP-AUTH-001` (User Authentication & Security) - Feature: `FEAT-AUTH-PASSWORD-MGMT` (Password Management) - Requirements: `REQ-SEC-003` (Account Recovery), `REQ-COMP-GDPR-004` (User Data Access) - Test Cases: `TC-AUTH-201` (password reset flow), `TC-SEC-105` (security validations) - Tasks: `TASK-AUTH-051` to `TASK-AUTH-059` - Dependencies: `US-AUTH-001` (User Authentication - completed), `TECH-019` (Email service - completed) - Architecture: `ADR-006` (Password Reset Token Design), `ADR-003` (JWT Sessions) --- ## Story ### User Story Statement **As a** registered user who forgot their password **I want** to reset my password via a secure email link **So that** I can regain access to my account without contacting customer support --- ### Story Context **Problem**: Users who forget passwords currently have no self-service recovery option. Support receives 200+ password reset requests per week, consuming 15 minutes per request (50 hours/week). 85% of users who forget passwords abandon checkout without completing purchase. **Value**: - **For Users**: Immediate account recovery (0 wait time vs. 2-4 hour support response) - **For Business**: Reduce support costs by ~$50K/year (50 hours/week × $20/hour × 52 weeks) - **For Business**: Recover ~$120K/year in abandoned cart revenue (85% of 200 users/week × $140 avg cart value × 52 weeks) **Scope**: - **Included**: Email-based password reset for registered users with verified email addresses - **Included**: Token-based reset link valid for 1 hour - **Included**: Password complexity validation - **Excluded**: SMS-based reset (future story: US-AUTH-007) - **Excluded**: Social account recovery (Google, Apple) - not applicable - **Excluded**: Support-initiated password reset (separate admin tool) **User Persona**: "Alice, Busy Professional" - 35 years old, shops online weekly, uses password manager but occasionally forgets master password. Values speed and security equally. Mobile-first user (70% of interactions on mobile). --- ### Supporting Information **User Journey**: This story fits at the "Account Access Problem" step in the user journey. User realizes they forgot password at Login Clicks "Forgot Password?" Receives email Resets password Resumes shopping. **Frequency**: Estimated 200 requests per week (4% of weekly logins), concentrated during holiday shopping seasons (300+ per week in November/December). **Current Workaround**: Users email support@example.com or use live chat. Average response time: 2-4 hours. Process is manual: support agent verifies identity via security questions, then manually resets password and emails user. 60% of users abandon and don't complete the support flow. --- ## Acceptance Criteria **INVEST Check** (Is this story ready?): - **Independent**: No dependencies on other in-sprint stories (US-AUTH-001 already complete) - **Negotiable**: Implementation details (token storage, email template) can be refined during development - **Valuable**: Delivers measurable business value ($170K/year cost savings + revenue recovery) - **Estimable**: Team estimated at 5 story points with high confidence - **Small**: Can complete in one 2-week sprint (5 points within team velocity of 20-25 points/sprint) - **Testable**: Clear pass/fail criteria for each acceptance criterion --- ### Criterion 1: Request Password Reset **Given** I am on the login page and forgot my password **When** I click the "Forgot Password?" link **Then** I am redirected to the password reset request page **And** I see a form with an email address input field **And** I see a "Send Reset Link" button **And** I see help text: "Enter your email address and we'll send you a link to reset your password" --- ### Criterion 2: Submit Valid Email Address **Given** I am on the password reset request page **When** I enter my registered email address "alice@example.com" and click "Send Reset Link" **Then** I see a success message: "If that email address is in our system, you'll receive a password reset link within 5 minutes. Check your spam folder if you don't see it." **And** I receive an email within 2 minutes with subject "Reset Your Password" **And** the email contains a password reset link valid for 1 hour **And** the email contains my account email address (for verification) **And** the email contains a "If you didn't request this, ignore this email" disclaimer **And** the reset link format is: `https://example.com/reset-password?token={secure_token}` **Quality Note**: Success message is intentionally vague (doesn't confirm email exists) to prevent account enumeration attacks. --- ### Criterion 3: Submit Unregistered Email Address **Given** I am on the password reset request page **When** I enter an email address that is NOT registered in the system **Then** I see the same success message as Criterion 2 (security: don't reveal whether email exists) **And** NO email is sent **And** a security log entry is created with the attempted email and IP address **Quality Note**: This prevents attackers from discovering which email addresses have accounts (account enumeration vulnerability). --- ### Criterion 4: Invalid Email Format **Given** I am on the password reset request page **When** I enter an invalid email format (e.g., "notanemail") and click "Send Reset Link" **Then** I see an inline error message: "Please enter a valid email address" **And** the email field is highlighted in red **And** the form does not submit --- ### Criterion 5: Reset Password via Email Link (Happy Path) **Given** I received a password reset email **When** I click the reset link within 1 hour **Then** I am redirected to the password reset form page **And** I see two password input fields: "New Password" and "Confirm New Password" **And** I see password requirements: - At least 8 characters - At least one uppercase letter - At least one lowercase letter - At least one number - At least one special character (!@#$%^&*) **And** I see a "Reset Password" button --- ### Criterion 6: Set New Password Successfully **Given** I am on the password reset form page with a valid token **When** I enter "NewSecurePass123!" in both password fields and click "Reset Password" **Then** my password is updated to the new password **And** I see a success message: "Your password has been reset successfully. You can now log in." **And** I am redirected to the login page after 3 seconds (with countdown) **And** I receive a confirmation email: "Your password was changed" **And** all my existing sessions are invalidated (logged out from all devices) **And** the reset token is marked as used and cannot be reused --- ### Criterion 7: Password Complexity Validation **Given** I am on the password reset form page **When** I enter a password that does not meet complexity requirements (e.g., "password") **Then** I see specific inline error messages for each failed requirement: - "Must contain at least one uppercase letter" - "Must contain at least one number" - "Must contain at least one special character" **And** the "Reset Password" button remains disabled **And** the form does not submit **When** I correct the password to meet all requirements (e.g., "Password123!") **Then** all error messages disappear **And** all requirements show green checkmarks **And** the "Reset Password" button becomes enabled --- ### Criterion 8: Password Mismatch **Given** I am on the password reset form page **When** I enter "Password123!" in the "New Password" field and "DifferentPassword123!" in "Confirm Password" field **Then** I see an error message: "Passwords do not match" **And** the form does not submit --- ### Criterion 9: Expired Reset Token **Given** I received a password reset email over 1 hour ago **When** I click the reset link **Then** I am redirected to an error page **And** I see the message: "This password reset link has expired. Password reset links are valid for 1 hour." **And** I see a "Request New Reset Link" button **And** clicking the button redirects me to the password reset request page --- ### Criterion 10: Already-Used Reset Token **Given** I have already successfully reset my password using a reset token **When** I try to use the same reset link again (token reuse attempt) **Then** I am redirected to an error page **And** I see the message: "This password reset link has already been used. For security, each link can only be used once." **And** I see a "Request New Reset Link" button --- ### Criterion 11: Rate Limiting **Given** I have requested 5 password reset emails in the last hour **When** I try to request a 6th reset email **Then** I see an error message: "Too many password reset requests. Please wait 1 hour before trying again, or contact support if you need immediate assistance." **And** no email is sent **And** a security log entry is created flagging potential abuse **Quality Note**: Rate limiting prevents attackers from flooding user inboxes with reset emails (denial of service / harassment attack). --- ### Acceptance Criteria Checklist - All happy path scenarios covered (Criteria 1, 2, 5, 6) - Edge cases and boundary conditions defined (Criteria 3, 9, 10, 11) - Error handling specified (Criteria 4, 7, 8) - Performance expectations stated (email within 2 minutes, page loads within 2 seconds) - Security requirements included (token expiry, rate limiting, account enumeration prevention) - Accessibility requirements specified (keyboard navigation, WCAG 2.1 AA - see NFRs below) --- ## Non-Functional Requirements ### Performance - **Response Time**: Password reset request page loads within 2 seconds (p95) - **Email Delivery**: Reset email sent within 2 minutes of request (p99) - **Token Validation**: Reset link validation completes within 500ms (p95) - **Throughput**: Support 100 concurrent password reset requests without degradation ### Security - **Token Cryptography**: Reset tokens must be cryptographically secure (256-bit entropy, generated via `crypto.randomBytes(32)`) - **Token Storage**: Tokens stored hashed in database (SHA-256), never in plaintext - **Token Expiry**: Tokens expire after 1 hour (3600 seconds), enforced server-side - **Token Single-Use**: Each token can only be used once; mark as used after successful reset - **Rate Limiting**: 5 reset requests per email per hour, 20 requests per IP per hour - **Account Enumeration Prevention**: Same success message regardless of email existence - **Session Invalidation**: All existing user sessions terminated after password change - **Audit Logging**: All reset requests, successes, failures logged with timestamp, IP, user agent - **HTTPS Only**: All password reset pages must use HTTPS (redirect HTTP to HTTPS) ### Usability - **User Experience**: - Clear, actionable error messages (no technical jargon) - Password strength indicator (visual feedback: weak/medium/strong) - Show/hide password toggle on password fields - **Accessibility**: - WCAG 2.1 Level AA compliant - Keyboard navigable (tab order: email field button link) - Screen reader compatible (proper ARIA labels) - Color contrast ratio 4.5:1 for all text - **Mobile**: - Touch-friendly on screens 320px wide - Email field uses `type="email"` for mobile keyboard optimization - No pinch/zoom required (responsive design) ### Reliability - **Uptime**: Password reset service must have 99.9% uptime (same as authentication service) - **Error Handling**: - Graceful degradation if email service is down (queue email, retry 3 times) - Display fallback message: "We're having trouble sending emails. Please try again in a few minutes or contact support." - **Monitoring**: Alert if email delivery failure rate > 5% or latency > 5 minutes ### Compliance - **GDPR**: - User can reset password without contacting support (data access control) - Password reset emails sent only to verified email addresses - Reset tokens and logs deleted after 90 days - **PCI DSS**: - Password complexity requirements meet PCI DSS 8.2.3 - Session invalidation meets PCI DSS 8.2.4 - **CAN-SPAM**: - Password reset emails include unsubscribe link (for non-transactional email footer) - Physical mailing address in email footer --- ## Dependencies ### Upstream Dependencies - **`US-AUTH-001`** (User Authentication): COMPLETED - **Why needed**: Password reset depends on existing user accounts and authentication infrastructure - **`TECH-019`** (Email Service Integration): COMPLETED - **Why needed**: Sending password reset emails requires functioning email service (SendGrid integration) - **`US-AUTH-002`** (Email Verification): COMPLETED - **Why needed**: Password reset only sent to verified email addresses ### Downstream Impact - **`US-AUTH-007`** (SMS-Based Password Reset): DEPENDS ON THIS STORY - **How**: SMS reset will reuse token generation and validation logic - **`US-SUPPORT-012`** (Support Dashboard - Account Recovery): DEPENDS ON THIS STORY - **How**: Support agents will use same password reset mechanism for manual resets ### External Dependencies - **SendGrid Email Service**: Production dependency - **Status**: Operational, 99.95% uptime SLA - **Risk**: Low (fallback: AWS SES configured as backup) - **Redis Token Store**: Production dependency - **Status**: Operational, Redis cluster with replication - **Risk**: Low (auth service already depends on Redis) --- ## Technical Considerations **Note**: This section provides guidance and context, not prescriptive solutions. Implementation team determines specific approaches. ### Integration Points **Systems**: - Authentication service (user lookup, password hashing) - Email service (SendGrid API for reset emails) - Redis (token storage with TTL) - PostgreSQL (user accounts, audit logs) **Data**: - **Read**: User account (email, hashed password, verification status) - **Write**: New hashed password in `users` table - **Create**: Reset token in Redis with TTL - **Create**: Audit log entries in `password_reset_logs` table - **Delete**: All user sessions from Redis on password change **APIs**: - `POST /api/auth/password-reset/request` - Request reset email - `GET /api/auth/password-reset/validate?token={token}` - Validate token before showing form - `POST /api/auth/password-reset/confirm` - Submit new password ### Implementation Guidance **Backend**: Token Generation: ```typescript // Generate cryptographically secure token const token = crypto.randomBytes(32).toString('hex'); // 64-character hex string const tokenHash = crypto.createHash('sha256').update(token).digest('hex'); // Store hashed token in Redis with 1-hour TTL await redis.setex(`password_reset:${tokenHash}`, 3600, JSON.stringify({ user_id: user.id, email: user.email, created_at: Date.now(), ip_address: req.ip })); // Send unhashed token via email (one-time use) await sendEmail({ to: user.email, subject: 'Reset Your Password', resetLink: `https://example.com/reset-password?token=${token}` }); ``` Password Update: ```typescript // Validate token, hash new password, invalidate sessions const tokenData = await redis.get(`password_reset:${tokenHash}`); if (!tokenData) { throw new Error('Invalid or expired token'); } const newPasswordHash = await bcrypt.hash(newPassword, 12); await db.users.update({ id: tokenData.user_id }, { password_hash: newPasswordHash }); // Invalidate all sessions await redis.del(`sessions:user:${tokenData.user_id}`); // Mark token as used await redis.del(`password_reset:${tokenHash}`); ``` **Frontend**: - Use React/Vue form with real-time password strength indicator - Debounce password validation (wait 300ms after user stops typing) - Show/hide password toggle (Material UI eye icon) - Loading states during API calls - Success/error toast notifications **Testing**: - **Unit tests**: Token generation, password validation, rate limiting logic - **Integration tests**: Full reset flow (request email reset login) - **E2E tests**: Selenium/Cypress tests for user flows - **Security tests**: Token reuse, expired token, rate limit enforcement ### Constraints **Platform**: - Browsers: Chrome, Firefox, Safari, Edge (latest 2 versions) - Mobile: iOS Safari, Android Chrome - Responsive: 320px to 1920px screen widths **Technology**: - Backend: Node.js 20+, Express.js - Frontend: React 18+, Material UI - Email: SendGrid API v3 - Token storage: Redis 7+ **Data**: - Reset tokens: 64-character hex strings (256-bit entropy) - Password hashes: bcrypt with cost factor 12 - Token TTL: 3600 seconds (1 hour) **Legal**: - GDPR Article 32 (security of processing) - PCI DSS 8.2.3 (password complexity) - CAN-SPAM Act (transactional email compliance) ### Risks **Technical Risk**: Email deliverability - **Risk**: Reset emails land in spam (10-15% typical spam rate) - **Impact**: Users can't reset passwords, contact support (defeats purpose) - **Mitigation**: - Use reputable email service (SendGrid) with good IP reputation - Implement DKIM, SPF, DMARC email authentication - Provide "Check spam folder" hint in success message - Add "Didn't receive email?" link to resend **Security Risk**: Token guessing - **Risk**: Attacker tries to brute-force reset tokens - **Impact**: Account takeover - **Mitigation**: - 256-bit entropy (2^256 possible tokens = computationally infeasible to guess) - 1-hour expiry limits attack window - Rate limiting prevents rapid guessing - Tokens hashed in database (even if database leaked, tokens unusable) **Usability Risk**: Password requirements too strict - **Risk**: Users frustrated by complexity requirements, give up - **Impact**: Abandoned resets, increased support tickets - **Mitigation**: - Real-time password strength feedback (visual indicator) - Show requirements before user types (not just errors after) - Allow spaces in passwords (passphrases are strong and memorable) - UX testing with 5-10 users before launch **Business Risk**: Support ticket increase during rollout - **Risk**: Users confused by new process, contact support anyway - **Impact**: Support costs don't decrease as expected - **Mitigation**: - Clear help text and examples in UI - FAQ page linked from reset form: "How do I reset my password?" - Train support team on new self-service process - Monitor support tickets for common confusion points, iterate on UX --- ## Task Breakdown **Total Estimated Hours**: 32h (matches 5 story points at team velocity of 6.5h/point) ### Backend Tasks - [x] **TASK-AUTH-051**: Design reset token generation and storage schema - 3h - Owner: Backend Engineer - Output: Token schema, Redis key structure, API endpoint design doc - [ ] **TASK-AUTH-052**: Implement `POST /api/auth/password-reset/request` endpoint - 4h - Owner: Backend Engineer - Output: API endpoint, token generation, email trigger - [ ] **TASK-AUTH-053**: Implement `GET /api/auth/password-reset/validate` endpoint - 2h - Owner: Backend Engineer - Output: Token validation endpoint - [ ] **TASK-AUTH-054**: Implement `POST /api/auth/password-reset/confirm` endpoint - 4h - Owner: Backend Engineer - Output: Password update logic, session invalidation, audit logging - [ ] **TASK-AUTH-055**: Add rate limiting middleware - 3h - Owner: Backend Engineer - Output: Rate limiter (5/email/hour, 20/IP/hour) ### Frontend Tasks - [ ] **TASK-AUTH-056**: Build password reset request form (email input) - 3h - Owner: Frontend Engineer - Output: React component, form validation, API integration - [ ] **TASK-AUTH-057**: Build password reset form (new password + confirm) - 4h - Owner: Frontend Engineer - Output: React component, real-time validation, password strength indicator - [ ] **TASK-AUTH-058**: Build error pages (expired token, used token) - 2h - Owner: Frontend Engineer - Output: React components, error handling ### Email + Testing Tasks - [ ] **TASK-AUTH-059**: Design and implement password reset email template - 2h - Owner: Frontend Engineer + UX Designer - Output: HTML email template, SendGrid template configuration - [ ] **TASK-AUTH-060**: Write unit tests for backend logic - 3h - Owner: Backend Engineer - Output: Jest tests for token generation, validation, password update - [ ] **TASK-AUTH-061**: Write integration tests for reset flow - 3h - Owner: Test Engineer - Output: API integration tests (request validate confirm) - [ ] **TASK-AUTH-062**: Write E2E tests for user flows - 4h - Owner: Test Engineer - Output: Cypress tests for full reset flows (happy + error paths) ### Documentation + Review - [ ] **TASK-AUTH-063**: Update API documentation - 1h - Owner: Technical Writer - Output: OpenAPI spec for 3 new endpoints - [ ] **TASK-AUTH-064**: Code review and refinement - 2h - Owner: Technical Lead - Output: Approved pull request --- ## Notes & Attachments ### Conversation Log - **2026-01-10**: Initial story drafted by Product Owner - **2026-01-15**: Security Auditor added security NFRs (token expiry, rate limiting, audit logging) - **2026-01-18**: Refined with team during backlog grooming, estimated at 5 points - **2026-01-22**: UX Designer added wireframes, simplified password requirements after user testing - **2026-01-25**: Technical Lead confirmed Redis token storage approach (ADR-006 created) ### Attachments - **Wireframes**: `@.aiwg/ux/wireframes/password-reset-flow.fig` - Figma designs for all screens - **Email Template**: `@.aiwg/ux/email-templates/password-reset.html` - Draft email design - **User Research**: `@.aiwg/ux/research/password-reset-usability-test.md` - Findings from 5 user tests - **API Contract**: `@.aiwg/api/specs/auth-password-reset-openapi.yaml` - OpenAPI 3.0 spec - **Architecture Decision**: `@.aiwg/architecture/decisions/ADR-006-password-reset-tokens.md` - Token design ADR ### Open Questions - [x] **Q1**: Should reset links work multiple times within 1 hour, or single-use only? - **Resolved**: Single-use for security (prevents token reuse after device compromise) - **Date**: 2026-01-18 - [x] **Q2**: What should rate limit be? 5 per hour too strict? - **Resolved**: 5 per email per hour is appropriate (prevents abuse), user can contact support if legitimate need - **Date**: 2026-01-18 - [x] **Q3**: Should we support "security question" alternative for users without email access? - **Resolved**: No, security questions are weak (easily guessable). User must contact support if lost email access. - **Date**: 2026-01-20 - [ ] **Q4**: Should password reset invalidate only web sessions, or mobile app sessions too? - **Pending**: Technical investigation of mobile app session architecture - **Assigned to**: Mobile Lead - **Target date**: 2026-02-05 --- ## Definition of Ready - Story statement clear, complete, follows "As a... I want... So that..." format - Acceptance criteria defined (11 criteria), testable, unambiguous - Story sized: 5 story points (team consensus) - Dependencies identified and resolved (US-AUTH-001, TECH-019 both complete) - NFRs documented (performance, security, usability, reliability, compliance) - Team reviewed, estimated, asked clarifying questions (backlog grooming 2026-01-18) - Product Owner confirmed priority (High) and business value ($170K/year) - No open questions remain that block implementation (Q4 doesn't block MVP) - Story is small enough for one sprint (5 points within 20-25 point velocity) --- ## Definition of Done ### Code Completion - [ ] All acceptance criteria met (11/11 passing) - [ ] Code follows team coding standards (ESLint, Prettier, TypeScript strict mode) - [ ] Code peer-reviewed and approved (minimum 2 reviewers: Backend Lead + Security Auditor) - [ ] No critical or high-severity code review findings - [ ] Code merged to `main` branch ### Testing - [ ] Unit tests pass with ≥80% coverage for new code (target: 90%+) - [ ] Integration tests pass (full reset flow validated) - [ ] E2E tests pass (Cypress tests for all user flows) - [ ] Security tests pass (token reuse, expiry, rate limiting) - [ ] Manual QA testing completed (QA engineer sign-off) - [ ] No high or critical severity defects remain ### Documentation - [ ] Code comments added for complex logic (token generation, rate limiting) - [ ] API documentation updated (OpenAPI spec published to developer portal) - [ ] User-facing help article created ("How to reset your password") - [ ] Release notes updated with user-visible feature announcement ### Deployment & Acceptance - [ ] Feature deployed to staging environment - [ ] Smoke tests pass in staging (password reset end-to-end) - [ ] Product Owner reviewed and accepted in staging - [ ] Deployed to production (canary: 5% traffic for 24h) - [ ] Production monitoring shows no errors (email delivery rate ≥95%, latency <2s) - [ ] No regression in existing authentication functionality - [ ] Story marked "Done" in Jira ### Additional Criteria (Security) - [ ] Security audit passed (Security Auditor review) - [ ] Penetration testing passed (no token guessing, no account enumeration) - [ ] GDPR compliance verified (data access control requirement met) - [ ] PCI DSS compliance verified (password complexity requirements met) --- ## Why This Example is Effective ### INVEST Adherence - **Independent**: No in-sprint dependencies, can be developed in isolation - **Negotiable**: Implementation details flexible (token storage, email service choice) - **Valuable**: Quantified value ($170K/year), clear user benefit - **Estimable**: Team estimated confidently (5 points, 32 hours) - **Small**: Fits in one sprint (5 of 20-25 points) - **Testable**: 11 clear acceptance criteria, all have pass/fail conditions ### Comprehensive Acceptance Criteria - 11 criteria covering happy path, edge cases, errors, security - Gherkin syntax (Given/When/Then) makes criteria unambiguous - Includes quality annotations explaining security decisions ### Security Rigor - Addresses account enumeration, token guessing, rate limiting, CSRF - References compliance requirements (GDPR, PCI DSS) - Security NFRs are specific and testable ### Realistic Sizing - Task breakdown totals 32 hours across backend, frontend, testing, docs - Matches 5 story points at team velocity of 6.5h/point - Tasks are right-sized (2-4 hours each), not too granular or too large ### Business Context - Quantified problem ($50K support costs, $120K abandoned carts) - Clear stakeholder interests (users, support, security, compliance) - Downstream impact identified (SMS reset, support dashboard depend on this) ### Traceability - Links to epic, feature, requirements, ADRs, tasks, test cases - References wireframes, research, API specs - Conversation log shows evolution of story through refinement --- ## Anti-Patterns Avoided ### ❌ Vague Acceptance Criteria **Bad**: "User can reset password" **Good**: 11 specific criteria with Given/When/Then format, covering happy path + 7 error scenarios ### ❌ Missing Security Considerations **Bad**: No mention of token expiry, rate limiting, or session invalidation **Good**: Comprehensive security NFRs, token design (256-bit entropy, SHA-256 hashing), rate limits (5/hour) ### ❌ Unrealistic Estimation **Bad**: "2 points" for a feature requiring email service, token management, rate limiting, etc. **Good**: "5 points" based on detailed task breakdown (32 hours), team consensus ### ❌ No Dependencies Identified **Bad**: Starting implementation without verifying email service is integrated **Good**: Explicit upstream dependencies (US-AUTH-001, TECH-019), confirmed as complete ### ❌ No Business Value **Bad**: "We need password reset because other sites have it" **Good**: Quantified value: $50K support cost reduction + $120K abandoned cart recovery --- **Story Version**: 1.3 **Template Version**: 1.1 **Example Author**: Requirements Analyst + Product Owner **Last Updated**: 2026-01-28 **Quality Review**: Passed (Security Auditor, Technical Lead, Test Architect)