OpenSkill + TEI Grade Deployment Checklist
Date: 2026-07-12
Migration: Elo → OpenSkill with TEI Grades
✅ PRE-DEPLOYMENT VERIFICATION
Build Status
- Engine builds: ✅
yarn build:enginepasses - Engine tests: ✅ 62/62 tests passing
- Functions build: ✅
npm run buildpasses in functions/ - No TypeScript errors: ✅ All files compile cleanly
Code Changes Verified
- Backend: Cloud Functions use OpenSkill + calculate displayGrade
- Client: stats-service.ts updated to OpenSkill
- Schema: displayGrade added to StoredRating
- Hysteresis: Implemented in TEI grade calculation
- UI Components: Created and ready (TeiDisplay, TeiChange, TeiGradeBadge)
📋 DEPLOYMENT STEPS
Step 1: Pre-Deployment Backup
What to backup:
- Current Firestore rules:
firestore.rules - Current Cloud Functions: Download from Firebase Console
How to backup:
# Backup rules
cp firestore.rules firestore.rules.backup
# Backup functions (already in Git)
git log --oneline -5 functions/
Note: User confirmed safe to wipe all data, but backup anyway for safety.
Step 2: Build Everything
cd /Volumes/Code/Warp12
# Build engine (warp12-engine)
yarn build:engine
# Build all packages
yarn build:all
# Build hosting (if deploying web app)
yarn build:all:hosting
# Verify builds succeeded
echo "✅ Builds complete"
Expected output:
- Engine:
✓ built in ~1s - No TypeScript errors
- All packages compile successfully
Step 3: Wipe Firebase Collections
⚠️ CRITICAL: User confirmed this is safe (no production data)
Collections to delete:
playerStats- All player rating dataratedMatches- All rated match recordspublishedLogs- Optional (for clean slate)
Option A: Firebase Console (Recommended)
- Go to https://console.firebase.google.com
- Select project:
warp-12 - Navigate to Firestore Database
- For each collection:
- Click collection name
- Click “Delete collection”
- Confirm deletion
Option B: Firebase CLI
# Install Firebase CLI if needed
npm install -g firebase-tools
# Login
firebase login
# Delete collections
firebase firestore:delete playerStats --project warp-12 --recursive -y
firebase firestore:delete ratedMatches --project warp-12 --recursive -y
firebase firestore:delete publishedLogs --project warp-12 --recursive -y
echo "✅ Collections wiped"
Verification:
playerStatscollection empty or deletedratedMatchescollection empty or deletedpublishedLogscollection empty or deleted
Step 4: Deploy Firestore Rules
cd /Volumes/Code/Warp12
# Deploy security rules (updated humanTei → humanRating)
yarn deploy:firestore
# Or directly:
# firebase deploy --only firestore:rules --project warp-12
What this deploys:
- Updated security rules with
humanRatinginstead ofhumanTei - Rules support new schema with
displayGradefield
Expected output:
✔ Deploy complete!
Verification:
- No deployment errors
- Rules updated in Firebase Console
Step 5: Deploy Cloud Functions
cd /Volumes/Code/Warp12
# Deploy all functions
yarn deploy:functions
# Or deploy specific functions:
# firebase deploy --only functions:reportPracticeAiMatch --project warp-12
# firebase deploy --only functions:reportOnlineMatch --project warp-12
# firebase deploy --only functions:setAcademyPlacement --project warp-12
What this deploys:
reportPracticeAiMatch- Solo vs AI rating updatesreportOnlineMatch- Online multiplayer rating updatessetAcademyPlacement- Academy placementapplyHumanTei- (internal) Human rating updatesapplyGroupTei- (internal) Charter/crew rating updates- Other supporting functions
Expected output:
✔ functions[...]: Successful update operation
✔ Deploy complete!
Verification:
- No deployment errors
- All functions deployed successfully
- Check Firebase Console → Functions → all listed
Step 6: Deploy Hosting (Optional)
Only if deploying web app:
cd /Volumes/Code/Warp12
# Deploy hosting
yarn deploy:hosting
# Or separately:
# firebase deploy --only hosting:Warp12 --project warp-12
# firebase deploy --only hosting:leaderboard --project warp-12
What this deploys:
- Main web app (The Bridge)
- Leaderboard SPA (optional)
Expected output:
✔ hosting[Warp12]: Deploy complete
✔ Deploy complete!
Step 7: Post-Deployment Verification
7.1 Test Solo vs AI Match
- Open app (locally or deployed)
- Sign in (anonymous auth)
- Start solo match vs AI (Commander, Points objective)
- Complete match (win or lose)
- Check Firestore:
playerStats/{uid}/localAi/commander/pointsExpected data:
{ "rating": { "mu": 25.5, // ← Should be ~25 for new player "sigma": 7.8, // ← Should decrease from 8.33 "matches": 1, "displayRating": 2.1, // ← μ - 3σ "displayGrade": "P" // ← Should be "P" (Provisional) }, "wins": 1 // ← 1 if won, 0 if lost } - Verify in UI:
- Profile page shows TEI (numeric or badge)
- No errors in console
- Rating updates correctly
Checklist:
- Match completes without errors
- Firestore document created
displayGradefield present- Rating values reasonable (μ ≈ 25-30, σ < 8.33)
- UI displays rating correctly
7.2 Test Hysteresis (Play Multiple Matches)
- Play 10-15 matches vs same AI opponent
- Watch σ decrease (should go from ~8.33 → ~3.0)
- Watch grade evolve:
- Start: P (σ ≥ 4.0)
- After 5-8 games: I (2.5 ≤ σ < 4.0)
- After 15+ games: C (1.5 ≤ σ < 2.5)
- Verify no flickering:
- At σ ≈ 4.0, should NOT flicker between I ↔ P
- At σ ≈ 2.5, should NOT flicker between C ↔ I
- Grade should be stable for several matches
Checklist:
- σ decreases with more matches
- Grade progresses: P → I → C
- No flickering at boundaries
displayGradeupdates correctly in Firestore
7.3 Test Online Match (If Available)
- Host rated sector (Warp 12, Points objective)
- Complete match with human players
- Report match (host calls reportOnlineMatch)
- Check Firestore:
playerStats/{uid}/humanRating/points
Expected data:
{
"rating": {
"mu": 25.0,
"sigma": 8.33,
"matches": 1,
"displayRating": 0.0,
"displayGrade": "P"
},
"wins": 1
}
Checklist:
- Online match rating updates
humanRatingfield populateddisplayGradepresent- No errors in function logs
7.4 Monitor Function Logs
# Watch real-time logs
firebase functions:log --project warp-12
# Or in Firebase Console:
# Functions → Logs → Filter by function name
Look for:
- ✅ Successful rating updates
- ✅ No errors or warnings
- ✅ Reasonable execution times (<1s)
Red flags:
- ❌ TypeError or undefined errors
- ❌ Schema validation failures
- ❌ Rating calculation errors
🚨 ROLLBACK PLAN
If something goes wrong:
Quick Rollback (Functions Only)
# Revert to previous functions deployment
firebase functions:config:rollback --project warp-12
Full Rollback (Functions + Rules)
# 1. Restore old rules
cp firestore.rules.backup firestore.rules
firebase deploy --only firestore:rules --project warp-12
# 2. Revert code changes
git log --oneline -10
git revert <commit-hash>
git push
# 3. Redeploy old functions
cd functions
npm run build
firebase deploy --only functions --project warp-12
Nuclear Option (Restore from Git)
# Find last known-good commit
git log --oneline --all | grep -i "elo"
# Reset to that commit
git reset --hard <commit-hash>
# Force push (if needed)
git push --force
# Redeploy
yarn build:all
yarn deploy:firebase
✅ POST-DEPLOYMENT CHECKLIST
Immediate (Within 1 hour)
- Solo AI match works
- Rating updates in Firestore
displayGradefield present- No function errors in logs
- UI displays ratings correctly
Short-term (Within 24 hours)
- Play 10+ matches to test hysteresis
- Verify grade progression (P → I → C)
- No flickering at boundaries
- Online matches work (if applicable)
- Leaderboard sorts correctly (if deployed)
Medium-term (Within 1 week)
- Monitor function costs
- Check for any edge cases
- Gather user feedback
- Plan UI polish (optional)
📊 SUCCESS METRICS
Technical Metrics
- ✅ 100% of matches result in rating updates
- ✅ 0 function errors per 1000 matches
- ✅ Average function execution time < 500ms
- ✅ No boundary flickering observed
User Experience Metrics
- ✅ Ratings feel “smoother” (no wild swings)
- ✅ Grade progression feels fair
- ✅ Hysteresis prevents frustrating flickers
- ✅ “V67” format is more engaging than “1532”
📝 NOTES
What’s Backward Compatible
- ✅ Old stats-service functions still work (displayPlayerObjectiveTei)
- ✅ Existing UI doesn’t break (still shows numbers)
- ✅ Old match history preserved (teiBefore/teiAfter still work)
What’s NOT Backward Compatible
- ❌ Old Elo ratings → OpenSkill ratings (requires wipe)
- ❌ Old schema (humanTei) → new schema (humanRating)
- ❌ Firestore queries need to use new field names
Migration Notes
- User confirmed: No production users, safe to wipe all data
- No migration script needed: Clean slate deployment
- Old data: Will be deleted, not converted
🎯 DEPLOYMENT DECISION
Recommendation: Deploy NOW
Why:
- ✅ All tests passing (62/62)
- ✅ All builds successful
- ✅ Backend complete and verified
- ✅ Client services updated and working
- ✅ User confirmed safe to wipe data
- ✅ UI polish is optional (can be done later)
Risk Level: LOW
- No production users
- Safe to wipe data
- Rollback plan ready
- Extensively tested
Go/No-Go: ✅ GO FOR DEPLOYMENT
Last Updated: 2026-07-12
Status: ✅ Ready for deployment
Approved By: (awaiting user confirmation)