PROJECT 06

Chat Application

Real-time messaging โ€” and handling a production emergency mid-project

โฑ ~75 min ยท 2 Sprints + Hotfix ยท Advanced

What's New in This Project

Projects 01-05 shipped without incidents. Real projects have production bugs. This project deploys Sprint 1 to production, then a critical bug appears. You'll use /agile-ship-hotfix for the structured emergency response and learn when to use /agile-ship-rollback.

โš ๏ธ Why This Matters

Every team ships bugs eventually. The difference between chaos and control is having a structured incident response. This project teaches you to replace panic with process: branch from main, reproduce with a test, fix minimally, review fast, deploy, and learn from it.

Roles You'll See in Action

RoleWhat they do in this projectWhen
๐Ÿ“‹ @poStructures your requirements into user stories, accepts completed workStory creation, sprint review, acceptance
๐Ÿ”„ @smFacilitates ceremonies, escalates severity during incidents, leads post-mortemSprint ceremonies, incident response
๐Ÿ—๏ธ @archEvaluates SSE vs WebSockets, recommends real-time approachProject setup, brainstorm
๐Ÿ‘จโ€๐Ÿ’ป @leadReviews code quality, conducts expedited hotfix reviews, co-leads post-mortemCode review, hotfix review, post-mortem
โŒจ๏ธ @devImplements features with TDD, writes hotfixImplementation, hotfix
๐Ÿงช @qaVerifies Definition of Done, checks test coverageDoD verification
๐Ÿš€ @devopsRuns CI pipeline, handles deployment, executes rollbackCI/CD, deploy, rollback
๐Ÿ›ก๏ธ @secReviews WebSocket authentication and authorizationSecurity review in Sprint 2

Phase 1: Project Setup

Step 1: Tell Claude what you want to build

๐Ÿ’ฌ You say

"I want to build a real-time chat app with rooms and messaging. Users should be able to create rooms, join them, and send messages that appear instantly for everyone in the room."

Step 2: @arch evaluates real-time approaches โ€” /agile-explore-brainstorm

Before choosing a technology, @arch evaluates the options. This is a deliberate contrast with Project 03 (Realtime Dashboard), which used SSE.

๐Ÿ’ฌ You type

/agile-explore-brainstorm I need real-time messaging for a chat app. Messages need to flow both directions โ€” users send and receive. Rooms with multiple users. Presence indicators (who's online).

๐Ÿ—๏ธ @arch responds with a scoring matrix:

## /agile-explore-brainstorm โ€” Results

### Problem Statement
Real-time bidirectional messaging for multi-user chat rooms.
Constraints: instant delivery, presence awareness, multiple rooms.

### Scoring Matrix

| Approach            | Feasibility | Maintainability | Performance | Risk | Total |
|---------------------|------------|-----------------|-------------|------|-------|
| WebSockets (ws/Socket.io) | 9/10  | 8/10            | 9/10        | 8/10 | 34    |
| SSE + POST fallback | 7/10       | 6/10            | 6/10        | 7/10 | 26    |
| Long polling         | 6/10       | 5/10            | 4/10        | 8/10 | 23    |
| WebTransport         | 5/10       | 5/10            | 10/10       | 4/10 | 24    |

### Recommendation
WebSockets โ€” clear winner for bidirectional chat.

### Why NOT SSE This Time?
In Project 03 (Realtime Dashboard), SSE was the right choice: the server
pushed updates and clients only read. Chat is different โ€” users SEND
messages too. SSE is unidirectional (server โ†’ client only). You'd need
a separate POST endpoint for sending, creating unnecessary complexity.

WebSockets give you a single persistent connection for both directions.

### What Would Change This
- If browser support is a hard constraint โ†’ SSE + POST fallback
- If you need UDP-like performance โ†’ WebTransport (experimental)
โœ… You decide

"WebSockets it is. The bidirectional requirement makes it the obvious choice โ€” SSE worked for the dashboard but won't work here."

Step 3: Scaffold and initialize

๐Ÿ’ฌ "Set up the project with WebSocket support and a test framework.
    Then run /agile-setup-init to populate the memory."

โ†’ @dev scaffolds: package.json, src/, WebSocket server setup, test config
โ†’ /agile-setup-init scans and populates memory files
โ†’ /agile-setup-onboard generates coding rules
โ†’ /agile-setup-health โ†’ โœ… All checks pass

Phase 2: Sprint 1 โ€” Core Chat

Step 4: Create user stories

๐Ÿ’ฌ /agile-story-create I need users to register with a username
   and password so they can be identified in chat rooms
   โ†’ @po creates US-001: "User registration" (3 pts)

๐Ÿ’ฌ /agile-story-create I need users to create new chat rooms
   with a name and join existing rooms
   โ†’ @po creates US-002: "Create and join rooms" (3 pts)

๐Ÿ’ฌ /agile-story-create I need users to send messages in a room
   and have them appear instantly for all room members via WebSocket
   โ†’ @po creates US-003: "Send and receive messages" (5 pts)

๐Ÿ’ฌ /agile-story-create I need to see the message history when
   joining a room so I can catch up on the conversation
   โ†’ @po creates US-004: "Message history" (2 pts)

Step 5: Sprint planning โ€” /agile-sprint-planning

๐Ÿ”„ @sm facilitates:

## Sprint Planning Output

### Sprint Goal
"Deliver a working chat app with rooms, messaging, and history"

### Sprint Backlog
| Story  | Title                    | Points | Priority |
|--------|--------------------------|--------|----------|
| US-001 | User registration        | 3      | P1       |
| US-002 | Create and join rooms    | 3      | P1       |
| US-003 | Send and receive messages | 5      | P1       |
| US-004 | Message history          | 2      | P1       |

### Capacity
- Committed: 13 points
- Sprint duration: 1 week

Step 6: Build US-001 โ€” User Registration (3 pts)

/agile-code-branch feature US-001 user-registration
/agile-story-plan US-001
/agile-code-tdd US-001
  ๐Ÿ”ด Test: POST /auth/register creates user โ†’ โŒ
  ๐ŸŸข Implement registration with hashed password โ†’ โœ…
  ๐Ÿ”ด Test: duplicate username returns 409 โ†’ โŒ
  ๐ŸŸข Add unique constraint check โ†’ โœ…
  ๐Ÿ”ด Test: missing fields return 400 โ†’ โŒ
  ๐ŸŸข Add validation โ†’ โœ…
/agile-code-ci           โ†’ โœ… All green
/agile-code-commit       โ†’ feat(auth): add user registration endpoint
/agile-code-pr           โ†’ PR created
/agile-code-pr-review    โ†’ โœ… Approved (๐ŸŸก S2: extract validation to middleware)
/agile-code-merge        โ†’ Squash merged to develop
/agile-story-dod         โ†’ โœ… DONE
/agile-story-accept      โ†’ โœ… ACCEPTED (3 points)

Step 7: Build US-002 โ€” Create and Join Rooms (3 pts)

/agile-code-branch feature US-002 rooms
/agile-story-plan US-002
/agile-code-tdd US-002
  ๐Ÿ”ด Test: POST /rooms creates a room โ†’ โŒ
  ๐ŸŸข Implement room creation โ†’ โœ…
  ๐Ÿ”ด Test: POST /rooms/:id/join adds user to room โ†’ โŒ
  ๐ŸŸข Implement join with WebSocket room subscription โ†’ โœ…
  ๐Ÿ”ด Test: joining nonexistent room returns 404 โ†’ โŒ
  ๐ŸŸข Add room existence check โ†’ โœ…
/agile-code-ci           โ†’ โœ… All green
/agile-code-commit       โ†’ feat(rooms): add create and join room endpoints
/agile-code-pr           โ†’ PR created
/agile-code-pr-review    โ†’ โœ… Approved
/agile-code-merge        โ†’ Squash merged to develop
/agile-story-dod         โ†’ โœ… DONE
/agile-story-accept      โ†’ โœ… ACCEPTED (3 points)

Step 8: Build US-003 โ€” Send and Receive Messages (5 pts)

/agile-code-branch feature US-003 messaging
/agile-story-plan US-003
/agile-code-tdd US-003
  ๐Ÿ”ด Test: WebSocket message in room broadcasts to all members โ†’ โŒ
  ๐ŸŸข Implement message broadcast via WebSocket โ†’ โœ…
  ๐Ÿ”ด Test: message persists to database โ†’ โŒ
  ๐ŸŸข Add message persistence layer โ†’ โœ…
  ๐Ÿ”ด Test: message to room user hasn't joined is rejected โ†’ โŒ
  ๐ŸŸข Add room membership check โ†’ โœ…
  ๐Ÿ”ด Test: message includes sender, timestamp, content โ†’ โŒ
  ๐ŸŸข Add message envelope format โ†’ โœ…
/agile-code-ci           โ†’ โœ… All green
/agile-code-commit       โ†’ feat(messages): add real-time messaging via WebSocket
/agile-code-pr           โ†’ PR created
/agile-code-pr-review    โ†’ โœ… Approved (๐ŸŸก S2: consider message size limit)
/agile-code-merge        โ†’ Squash merged to develop
/agile-story-dod         โ†’ โœ… DONE
/agile-story-accept      โ†’ โœ… ACCEPTED (5 points)

Step 9: Build US-004 โ€” Message History (2 pts)

/agile-code-branch feature US-004 message-history
/agile-story-plan US-004
/agile-code-tdd US-004
  ๐Ÿ”ด Test: GET /rooms/:id/messages returns last 50 messages โ†’ โŒ
  ๐ŸŸข Implement paginated message history โ†’ โœ…
  ๐Ÿ”ด Test: empty room returns empty array โ†’ โŒ
  ๐ŸŸข Handle edge case โ†’ โœ…
/agile-code-ci           โ†’ โœ… All green
/agile-code-commit       โ†’ feat(messages): add message history endpoint
/agile-code-pr           โ†’ PR created
/agile-code-pr-review    โ†’ โœ… Approved
/agile-code-merge        โ†’ Squash merged to develop
/agile-story-dod         โ†’ โœ… DONE
/agile-story-accept      โ†’ โœ… ACCEPTED (2 points)

Step 10: Sprint 1 ceremonies

/agile-sprint-review
  Sprint Goal: "Deliver a working chat app with rooms, messaging, and history"
  Sprint Goal Met: โœ… Yes
  Velocity: 13/13 points (100%)

/agile-sprint-retro
  What went well: WebSocket architecture clean, TDD caught edge cases
  To improve: Need encoding tests for user input fields
  Action items: add input sanitization tests in Sprint 2

/agile-memory-learn โ†’ Saved Sprint 1 learnings

Step 11: Deploy Sprint 1 to production

This is the critical step. The app goes live and real users start using it.

/agile-ship-changelog
  ## Changelog: v1.0.0
  ### Added
  - User registration with secure password hashing (US-001)
  - Create and join chat rooms (US-002)
  - Real-time messaging via WebSockets (US-003)
  - Message history with pagination (US-004)

/agile-ship-release v1.0.0
  ๐Ÿš€ @devops: Release v1.0.0
    Branch: release/v1.0.0 from develop
    CI: โœ… Green
    Merged to main โœ…
    Tagged: v1.0.0 โœ…
    Back-merged to develop โœ…

/agile-ship-deploy
  ๐Ÿš€ @devops: Deployed v1.0.0
    Smoke tests: โœ… All endpoints responding
    WebSocket connections: โœ… Healthy
    Health check: โœ…
โœ… v1.0.0 is live

All smoke tests pass. Users start creating rooms and chatting. Everything looks good... for about two days.

Phase 3: Production Incident! (The Key Teaching Phase)

๐Ÿšจ The Bug

Two days after deploy, users report: "Messages in rooms with special characters (emojis, accented characters) in the room name cause the app to crash." A user created a room called "cafe-โ˜•" and every message sent to it crashes the server.

Step 12: Assess severity

๐Ÿ’ฌ You say

"Users are reporting crashes when room names have special characters like emojis or accents. Production is affected โ€” the app crashes for any room with these characters."

๐Ÿ”„ @sm assesses:

## Incident Assessment

Severity: S0 โ€” CRITICAL
Impact: App crashes for affected users. Any room with non-ASCII
characters in the name is unusable. Server restarts but crashes
again on next message to affected rooms.

Decision: Trigger the hotfix workflow immediately.
Do NOT wait for Sprint 2 planning. This is a production emergency.

Step 13: /agile-ship-hotfix โ€” The Full Emergency Flow

This is the most important section of Project 06. Every step of the hotfix workflow is shown in detail because this is what you'll do under pressure in real projects.

Step 13a: Create hotfix branch from main

๐Ÿ’ฌ You type

/agile-code-branch hotfix crash-special-chars

โŒจ๏ธ @dev: Hotfix branch created
  Branch: hotfix/crash-special-chars
  From: main (v1.0.0)
  Linked to: INCIDENT-001
โš ๏ธ Why branch from main, NOT develop?

main reflects what's in production. develop may already have Sprint 2 work that's not ready to ship. If you branch from develop, your hotfix deploy could include untested Sprint 2 code โ€” turning one bug into many. Always branch hotfixes from main.

Step 13b: Reproduce the crash with TDD

๐Ÿ’ฌ You type

/agile-code-tdd Reproduce the crash: room name with emoji causes message send to fail

๐Ÿ”ด RED โ€” Write a test that reproduces the crash

// test/hotfix-special-chars.test.js
test('sending a message to a room with emoji name should succeed', async () => {
  const room = await createRoom({ name: 'cafe-โ˜•' });
  const ws = await connectToRoom(room.id, testUser);

  const response = await sendMessage(ws, {
    roomId: room.id,
    content: 'Hello from the cafe!'
  });

  expect(response.status).toBe('delivered');
  expect(response.content).toBe('Hello from the cafe!');
});

// Result: โŒ FAIL โ€” TypeError: Cannot read properties of undefined
// (reading 'normalize') โ€” the room name encoding crashes
// the message routing lookup

๐ŸŸข GREEN โ€” Fix the encoding issue (minimal fix)

// src/rooms/normalize.js โ€” BEFORE (broken)
function normalizeRoomName(name) {
  return name.toLowerCase().replace(/[^a-z0-9-]/g, '');
}

// src/rooms/normalize.js โ€” AFTER (fixed)
function normalizeRoomName(name) {
  return name.normalize('NFC').toLowerCase();
}

// The bug: the old regex stripped ALL non-ASCII characters,
// turning "cafe-โ˜•" into "cafe-" which then failed to match
// the stored room ID in the WebSocket routing table.

// Result: โœ… PASS
๐Ÿ’ก Notice the fix

The fix is two lines. Hotfixes must be minimal โ€” fix the bug, nothing else. This is not the time to refactor, add features, or clean up tech debt. The smaller the change, the lower the risk.

Step 13c: Run CI

/agile-code-ci
  ๐Ÿš€ @devops: CI Pipeline Results
    Build:    โœ…
    Tests:    โœ… 24/24 passing (including new hotfix test)
    Lint:     โœ… 0 errors
    Security: โœ… No vulnerabilities

All existing tests still pass โ€” the fix doesn't introduce regressions.

Step 13d: Expedited code review

/agile-code-pr-review

๐Ÿ‘จโ€๐Ÿ’ป @lead: EXPEDITED Hotfix Review (30 min max, not 24 hours)

| # | Check                          | Status |
|---|--------------------------------|--------|
| 1 | Does it fix the reported issue? | โœ…     |
| 2 | Is the fix minimal?            | โœ… (2 lines changed) |
| 3 | Does it introduce regressions? | โœ… No (all 24 tests pass) |
| 4 | Is the new test adequate?      | โœ… Covers the exact scenario |

Score: 9/10
Verdict: โœ… APPROVED โ€” ship it
โš ๏ธ Expedited, not skipped

Hotfix reviews are fast (30 minutes max) but never skipped. @lead checks three things: Does it fix the issue? Does it introduce regressions? Is it minimal? Skipping review under pressure is how you turn one production bug into two.

Step 13e: Merge to main AND develop

/agile-code-merge

โŒจ๏ธ @dev: Hotfix merge complete
  1. Merged hotfix/crash-special-chars โ†’ main โœ…
  2. Tagged: v1.0.1 โœ…
  3. Merged hotfix/crash-special-chars โ†’ develop โœ…
  4. Branch hotfix/crash-special-chars deleted
๐Ÿšซ Don't forget the develop merge!

The hotfix must merge into both main and develop. If you only merge to main, the fix is lost the next time you release from develop. Your v1.1.0 release would reintroduce the bug.

Step 13f: Deploy the hotfix

/agile-ship-deploy

๐Ÿš€ @devops: Deployed v1.0.1
  Smoke tests: โœ… All endpoints responding
  Hotfix verification: โœ… Room "cafe-โ˜•" โ€” messages delivered
  Health check: โœ…
  WebSocket connections: โœ… Stable

Step 13g: What if the deploy FAILS?

Sometimes the hotfix deploy itself causes problems. This is when you use /agile-ship-rollback.

๐Ÿ’ฌ You would type (if deploy failed)

/agile-ship-rollback --reason "hotfix deploy caused 500 errors on the chat endpoint"

## /agile-ship-rollback โ€” Emergency Rollback

๐Ÿš€ @devops executes:
  1. Rolling back to: v1.0.0
  2. Deploy v1.0.0: โœ… Complete
  3. Health checks: โœ… All passing
  4. WebSocket connections: โœ… Re-established
  5. 500 errors: โœ… Resolved

### Status
- Production is back on v1.0.0
- The original bug (special chars) still exists
- Team has time to investigate why the hotfix deploy failed

### Next Steps
- Debug the deployment issue (not the code fix)
- Re-attempt deploy after fixing deployment config
โš ๏ธ Rollback vs Fix-Forward

Rollback when the deploy itself is broken โ€” you need production stable NOW and can debug later. Fix-forward when the code fix is almost right but needs a small tweak โ€” rolling back would reintroduce the original bug. Rule of thumb: rollback is faster than debugging under pressure.

Step 13h: Post-mortem

After the incident is resolved, ๐Ÿ”„ @sm and ๐Ÿ‘จโ€๐Ÿ’ป @lead conduct a blameless post-mortem. The goal is learning, not blame.

## Blameless Post-Mortem โ€” INCIDENT-001

### Timeline
- Day 0: v1.0.0 deployed. All smoke tests pass.
- Day 2: First user report โ€” room "cafe-โ˜•" crashes on message send.
- Day 2 + 1h: Incident triaged as S0.
- Day 2 + 2h: Hotfix branch created, test written, fix applied.
- Day 2 + 3h: Expedited review approved. v1.0.1 deployed.
- Day 2 + 3.5h: Verified fix in production. Incident closed.

### Root Cause
UTF-8 encoding not handled in room name normalization.
The normalizeRoomName() function used a regex that stripped
all non-ASCII characters, breaking the room ID lookup for
any room with emojis, accents, or other Unicode characters.

### Why It Wasn't Caught
- No test cases used non-ASCII characters in room names
- Smoke tests only used ASCII room names
- No fuzzing or Unicode-aware input testing

### Action Items
| # | Action                                           | Owner | Due       |
|---|--------------------------------------------------|-------|-----------|
| 1 | Add encoding tests for ALL user-input fields     | @qa   | Sprint 2  |
| 2 | Add monitoring/alerting for crash rate spikes     | @devops | Sprint 2 |
| 3 | Add Unicode room names to smoke test suite        | @dev  | Sprint 2  |
| 4 | Review all string normalization functions          | @lead | Sprint 2  |
โœ… Incident resolved

Total time from report to fix in production: 3.5 hours. That's the power of a structured hotfix workflow. No panic, no guessing โ€” just process: branch โ†’ test โ†’ fix โ†’ review โ†’ deploy โ†’ learn.

Phase 4: Sprint 2 โ€” Enhanced Features

After the incident, the team continues. The post-mortem action items are incorporated alongside new features.

Step 14: Create Sprint 2 stories

๐Ÿ’ฌ /agile-story-create I need to show which users are currently
   online in a room so people know who's available to chat
   โ†’ @po creates US-005: "Online presence indicators" (3 pts)

๐Ÿ’ฌ /agile-story-create I need users to react to messages
   with emoji reactions (like ๐Ÿ‘, โค๏ธ, ๐Ÿ˜‚) without sending
   a separate message
   โ†’ @po creates US-006: "Message reactions" (2 pts)

๐Ÿ’ฌ /agile-story-create I need users to receive notifications
   when new messages arrive in rooms they've joined but aren't
   currently viewing
   โ†’ @po creates US-007: "Room notifications" (5 pts)

Step 15: Sprint planning

๐Ÿ”„ @sm facilitates:

## Sprint 2 Planning

### Sprint Goal
"Add presence, reactions, and notifications to enhance the chat experience"

### Sprint Backlog
| Story  | Title                   | Points | Priority |
|--------|-------------------------|--------|----------|
| US-005 | Online presence         | 3      | P1       |
| US-006 | Message reactions       | 2      | P1       |
| US-007 | Room notifications      | 5      | P1       |

### Capacity
- Velocity (Sprint 1): 13 points
- Committed: 10 points (conservative โ€” accounting for incident overhead)

### Notes
- Post-mortem action items (encoding tests, monitoring) are
  technical tasks, not stories โ€” woven into Sprint 2 work

Step 16: Build US-005 โ€” Online Presence (3 pts)

/agile-code-branch feature US-005 online-presence
/agile-story-plan US-005
/agile-code-tdd US-005
  ๐Ÿ”ด Test: joining room broadcasts "user joined" to members โ†’ โŒ
  ๐ŸŸข Implement presence events on WebSocket connect โ†’ โœ…
  ๐Ÿ”ด Test: leaving room broadcasts "user left" โ†’ โŒ
  ๐ŸŸข Implement disconnect detection with heartbeat โ†’ โœ…
  ๐Ÿ”ด Test: GET /rooms/:id/members returns online users โ†’ โŒ
  ๐ŸŸข Implement members endpoint โ†’ โœ…
/agile-code-ci           โ†’ โœ… All green
/agile-code-commit       โ†’ feat(presence): add online presence indicators
/agile-code-pr           โ†’ PR created
/agile-code-pr-review    โ†’ โœ… Approved
/agile-code-merge        โ†’ Squash merged to develop
/agile-story-dod         โ†’ โœ… DONE
/agile-story-accept      โ†’ โœ… ACCEPTED (3 points)

Step 17: Build US-006 โ€” Message Reactions (2 pts)

/agile-code-branch feature US-006 reactions
/agile-story-plan US-006
/agile-code-tdd US-006
  ๐Ÿ”ด Test: adding reaction to message broadcasts to room โ†’ โŒ
  ๐ŸŸข Implement reaction WebSocket events โ†’ โœ…
  ๐Ÿ”ด Test: message includes reaction counts in history โ†’ โŒ
  ๐ŸŸข Add reaction aggregation to message query โ†’ โœ…
/agile-code-ci           โ†’ โœ… All green
/agile-code-commit       โ†’ feat(reactions): add emoji reactions to messages
/agile-code-pr           โ†’ PR created
/agile-code-pr-review    โ†’ โœ… Approved
/agile-code-merge        โ†’ Squash merged to develop
/agile-story-dod         โ†’ โœ… DONE
/agile-story-accept      โ†’ โœ… ACCEPTED (2 points)

Step 18: Security review before notifications โ€” /agile-security-review

Before building notifications (which require persistent WebSocket connections), ๐Ÿ›ก๏ธ @sec reviews the WebSocket authentication model.

๐Ÿ’ฌ You type

/agile-security-review Review WebSocket authentication โ€” we're about to add persistent notification connections and need to make sure auth is solid.

๐Ÿ›ก๏ธ @sec responds:

## /agile-security-review โ€” WebSocket Auth Review

### Findings

| # | Severity | Finding                                    | Risk                        |
|---|----------|--------------------------------------------|-----------------------------|
| 1 | ๐Ÿ”ด S0   | Missing token validation on WS upgrade     | Any client can connect      |
|   |          | handshake โ€” auth only checked on HTTP       | without authentication      |
|   |          | endpoints, not on WebSocket connection      |                             |
| 2 | ๐ŸŸก S2   | No token expiry check on long-lived WS     | Revoked tokens remain       |
|   |          | connections                                 | active until disconnect     |
| 3 | ๐ŸŸก S2   | Room membership not re-validated on         | Users could receive         |
|   |          | reconnect                                   | messages from left rooms    |

### Required Before Sprint 2 Release
Fix #1 is mandatory โ€” S0 security finding.

### Recommendation
Add JWT validation to the WebSocket upgrade handshake.
Reject connections with invalid/missing/expired tokens
BEFORE the upgrade completes.
๐Ÿšซ S0 Security Finding

The WebSocket upgrade handshake accepts connections without checking the JWT token. This means unauthenticated users can connect and receive messages. This must be fixed before the next release.

Step 19: Fix the security finding with TDD

/agile-code-tdd Fix S0: validate JWT on WebSocket upgrade handshake

๐Ÿ”ด RED:
test('WS connection without token is rejected', async () => {
  const ws = new WebSocket('ws://localhost:3000/chat');
  await expect(waitForOpen(ws)).rejects.toThrow('401');
});
// โŒ FAIL โ€” connection succeeds without token

๐ŸŸข GREEN:
// src/websocket/auth.js
server.on('upgrade', (request, socket, head) => {
  const token = parseToken(request);
  if (!token || !verifyJWT(token)) {
    socket.write('HTTP/1.1 401 Unauthorized\r\n\r\n');
    socket.destroy();
    return;
  }
  // ... proceed with upgrade
});
// โœ… PASS

/agile-code-ci โ†’ โœ… All green (including existing WS tests updated with auth)

Step 20: Build US-007 โ€” Room Notifications (5 pts)

/agile-code-branch feature US-007 notifications
/agile-story-plan US-007
/agile-code-tdd US-007
  ๐Ÿ”ด Test: user receives notification for message in joined room โ†’ โŒ
  ๐ŸŸข Implement notification dispatch via WebSocket โ†’ โœ…
  ๐Ÿ”ด Test: no notification for room user is currently viewing โ†’ โŒ
  ๐ŸŸข Track active room per connection โ†’ โœ…
  ๐Ÿ”ด Test: notification includes room name, sender, preview โ†’ โŒ
  ๐ŸŸข Add notification payload format โ†’ โœ…
  ๐Ÿ”ด Test: unread count increments per room โ†’ โŒ
  ๐ŸŸข Add unread counter per user per room โ†’ โœ…
/agile-code-ci           โ†’ โœ… All green
/agile-code-commit       โ†’ feat(notifications): add room notifications with unread counts
/agile-code-pr           โ†’ PR created
/agile-code-pr-review    โ†’ โœ… Approved
/agile-code-merge        โ†’ Squash merged to develop
/agile-story-dod         โ†’ โœ… DONE
/agile-story-accept      โ†’ โœ… ACCEPTED (5 points)

Step 21: Sprint 2 ceremonies and release

/agile-sprint-review
  Sprint Goal Met: โœ… Yes
  Velocity: 10/10 points (100%)

/agile-sprint-retro
  What went well: Security review caught critical auth gap before release
  What went well: Post-mortem action items all addressed
  To improve: Should run /agile-security-review earlier in the sprint
  Action items: security review in Sprint 0 for future projects

/agile-memory-learn โ†’ Saved Sprint 2 learnings

/agile-ship-changelog
  ## Changelog: v1.1.0
  ### Added
  - Online presence indicators (US-005)
  - Emoji reactions on messages (US-006)
  - Room notifications with unread counts (US-007)
  ### Fixed
  - JWT validation on WebSocket upgrade handshake (Security)

/agile-ship-release v1.1.0
  ๐Ÿš€ @devops: Release v1.1.0
    Tagged: v1.1.0 โœ…
    Merged to main โœ…
    Back-merged to develop โœ…

/agile-ship-deploy
  ๐Ÿš€ @devops: Deployed v1.1.0
    Smoke tests: โœ… (now includes Unicode room names!)
    Health check: โœ…

What You Built

MetricValue
Stories completed7/7
Story points delivered23 (Sprint 1: 13, Sprint 2: 10)
Sprint goals metโœ… Both
Production incidents1 (resolved in 3.5 hours)
Release versionsv1.0.0, v1.0.1 (hotfix), v1.1.0
Security findings fixed1 S0 (WebSocket auth)
Roles involved@po, @sm, @arch, @lead, @dev, @qa, @devops, @sec
โœ… Key Takeaway

Production bugs are not failures โ€” they're part of shipping software. The hotfix workflow gives you a structured response: branch from main โ†’ reproduce with test โ†’ fix minimally โ†’ expedited review โ†’ deploy โ†’ post-mortem. Panic is replaced by process.

You also learned that security reviews (/agile-security-review) catch vulnerabilities before they reach users, and rollback (/agile-ship-rollback) is your safety net when a deploy goes wrong.

New Commands Introduced

CommandWhat It DoesWhen You Used It
/agile-ship-hotfixStructured emergency fix workflow: branch from main, minimal fix, expedited review, deployPhase 3 โ€” production crash with special characters
/agile-ship-rollbackEmergency rollback to previous stable version when a deploy failsPhase 3 โ€” as fallback if hotfix deploy failed
/agile-security-reviewSecurity audit of specific components (auth, input handling, etc.)Phase 4 โ€” WebSocket auth review before notifications

Hotfix Flow

๐Ÿšจ
IncidentAssess severity
๐ŸŒฟ
BranchFrom main!
๐Ÿ”ด๐ŸŸข
TDDReproduce + fix
โš™๏ธ
CIMust pass
๐Ÿ”€
ReviewExpedited (30m)
๐Ÿ”—
Mergemain + develop
๐Ÿš€
DeployOr rollback
๐Ÿ“
Post-mortemBlameless

๐Ÿง  Knowledge Check

Why does the hotfix branch from main, not develop?

๐Ÿง  Knowledge Check

Is code review skipped for hotfixes?

๐Ÿง  Knowledge Check

When should you rollback instead of fix-forward?