功能案例走查(統整版V2)
本文件透過具體場景演示,讓讀者看到所有新機制在實際情境中如何運作。主案例繼承 V1 統整版的「任務提醒通知設定」功能 13 節點走查,並補充四個新場景:Hotfix 緊急應對、掉車去污名化、QA 批次視窗、String Freeze。每個場景用旁白第三人稱撰寫,真實呈現各角色的操作和心理狀態。每個場景結束後有「機制設計說明」,解釋場景背後的設計決策。
主案例:任務提醒通知設定(13 節點走查,更新 Testing Notes 三方確認)
案例設定
功能名稱:任務提醒通知設定(iOS + Android)
背景:用戶反映無法自訂 Forest 的任務提醒頻率,PO 決定新增「提醒時間設定」功能,讓用戶可以設定每天的提醒時間和頻率。這個功能涉及 iOS 和 Android 兩個平台的通知權限機制,是同步發布的典型場景。
參與角色:
| 角色 | 人員 | 本案例的操作 |
|---|---|---|
| PO | Shawn | 建立功能 Issue、填寫規格與初始 Testing Notes |
| RM | Sherridy | 分配版本號、管理版本列車、執行掉車決策 |
| RD | Keith(iOS)/ Ezou(Android) | 開發、包版、PR、補充技術邊界 Testing Notes |
| QA | Fei Chen | 展測項、批次視窗測試、兩階段測項補充 |
| MKT | 行銷夥伴 | 確認多國翻譯 |
| Shawn | 送審負責人 | 提交審核、正式發布 |
目標版本:Forest v5.8.0(iOS + Android 同步發布)
Feature Freeze 日期:2025/03/08
節點 1 — Planning:PO 建立功能 Issue 並填寫初始 Testing Notes
時間:Sprint Planning 結束後,當天下午
Shawn 打開 Linear,建立新 Issue,使用「功能規劃」Template。他在「測試注意事項 - 重點觀測項目」欄位填寫:
重點觀測項目(PO 初始填寫 — 三方確認機制第一方):
- iOS 和 Android 的通知權限流程不同,需分別測試
- 用戶關閉通知後再開啟,設定值應保留(這是最容易踩到的邊界)
- 舊版 Forest 用戶升級後,預設值行為待確認
「技術邊界」欄位留空,等 RD 開發中補充。「平台差異」欄位留空,等 RD 補充。
Issue 建立後,Linear Automation 5(無條件提醒)自動在 Issue 上發 Comment:
💡 PO / RD 提醒:此 Issue 已進入開發流程。
請確認「測試注意事項」的以下欄位是否已填寫:
- 重點觀測項目(PO 負責,Planning 時填寫)
- 技術邊界(RD 負責,開發中補充)
若已填寫請忽略此提醒。若尚未填寫請在開發完成前補充。
Shawn 在 Comment 回覆:「✅ 重點觀測項目已填寫,包含通知權限差異和設定值保留兩個重點。技術邊界等 Keith 和 Ezou 補充。」
此時 Linear 的狀態:Issue FOR-234 建立,狀態 Planning,Testing Notes 第一方已填。
節點 2 — RM 決定版本號:分配到 v5.8.0
時間:Planning 後 1-2 天內
Sherridy 在 Planning 狀態的 Issue 清單中看到 FOR-234。她確認 v5.8.0 的 Feature Freeze 日期(已在 Project Milestone 設定為 03/08),評估這個功能在 Freeze 前完成沒有明顯風險,將 Issue 加入 Forest v5.8.0 Release Project。
同時,Sherridy 完成 Calendar 提醒設定:
Google Calendar 新增事件:
名稱:v5.8.0 Feature Freeze 前 2 天提醒
日期:03/06(Freeze 前 2 天)09:00
提醒:「今天起 2 天後是 Feature Freeze。掃描 In Development 的 Issue。」
此時 Linear 的狀態:FOR-234 在 Forest v5.8.0 Release Project,Fei Chen 收到 QA 通知。
節點 3 — QA 第一階段展測項:並行開始
時間:Planning 完成後,Fei Chen 在下個批次視窗中處理
Fei Chen 打開「QA 待測 Queue」視圖,看到 FOR-234 出現(狀態 Planning,已分配版本)。她在批次視窗中讀取 Testing Notes,建立第一階段 Sub-issues(共 10 個),涵蓋 PO 的重點觀測項目和基礎 AC。
在 FOR-234 Comment 留言:「第一階段測項已建立,共 10 個。等 RD 技術邊界補充後,Ready for Test 時會重新確認。」
節點 4 — In Development:RD 補充 Testing Notes(三方確認機制第二方)
時間:Sprint 開始,Keith 和 Ezou 依功能排程開發
Keith 建立 PR,PR 標題含 FOR-234,Linear 自動將 Issue 狀態改為 In Review。開發到第三天,Keith 發現 UserDefaults 機制有邊界情況,在 FOR-234 的「技術邊界」欄位補充:
技術邊界(Keith - 02/19 補充):
- iOS:設定值存在 UserDefaults(key: notificationTime)
「在系統設定中關閉通知 App 後再開啟」會觸發 UserDefaults 重讀邏輯,
這條路徑需要特別測試。
- iOS:首次安裝預設應為 08:00(不是空值)
平台差異(Keith + Ezou 補充):
- iOS:通知彈窗只能出現一次,被拒絕後需引導用戶去系統設定
- Android:Android 12 和 Android 13 有不同的通知權限 API,
需要各準備一台裝置測試
Keith 送出 PR 時,在 PR Template 填寫確認欄位:
## Testing Notes 確認
- [x] 已更新 Linear Issue 的測試注意事項「技術邊界」欄位
→ Y(補充了 UserDefaults 重讀邏輯和 Android 版本差異)
## Impact Scope
- 本 PR 影響範圍:通知設定的 UserDefaults 讀寫路徑
- 是否影響現有功能?N(新功能,無回歸風險)
機制設計說明:PR Template 的 Testing Notes 確認欄位是 V2 新增的設計。Linear 沒辦法阻止 RD 在 Testing Notes 空白時就改 Issue 狀態,但在 PR Review 這個唯一有工具強制節點(PR 必須被 Reviewer 看到),插入確認欄位,讓「忘記補充」變成「主動確認後選擇不補充」。這是人工紀律的最近似工具強制。
節點 5 — Test Requested:PR Merge 自動觸發 + 版本確認
時間:Keith 的 PR merge 到 staging
Keith 的 PR 合併到 staging/ios-* 後,Linear Automation 自動將 FOR-234 狀態改為 Test Requested,QA 通知自動發送。
Keith 同時在 FOR-234 留 iOS 手動確認 Comment(標準模板):
iOS 版本確認通知
版本:Build 312(TestFlight)
PR 合併時間:03/07 14:30
功能:任務提醒通知設定(FOR-234)
@Fei Chen 可以在 TestFlight 下載新版本測試。
如果 TestFlight 沒有看到新 Build,請 DM 通知我。
Ezou 的 Android PR 合併後,Slack android-test 自動通知:
✅ Android 新版本可測試
功能:任務提醒通知設定(FOR-234)
版本號:5.8.0-ALPHA3
@Fei Chen 請確認版本號包含 -ALPHA3
節點 5.5 — QA 第二階段測項補充(Test Requested 時)
時間:Fei Chen 在週四批次視窗(14:00-18:00)打開 Queue
Fei Chen 打開「QA 待測 Queue」視圖,FOR-234 出現在列表頂部(Priority: High)。這是批次視窗的第一個工作。
她打開 Issue,重新讀取 Testing Notes——這是三方確認機制的第三方(QA 雙重讀取)。她發現 Keith 在第一階段展測項之後補充了技術邊界:
QA 雙重讀取確認:
第一方(PO 初始):通知權限差異、設定值保留 ✅ 已有對應測項
第二方(RD 技術邊界):
Keith 補充:UserDefaults 重讀邏輯(第一階段無法預見)← 需要新增測項
Keith 補充:首次安裝預設 08:00(第一階段無法預見)← 需要新增測項
Ezou 補充:Android 12 vs 13 分開測試(第一階段未細分)← 需要新增測項
第三方(Jimmy,如有):Integration Test 尚未補充,確認 CI 跑完後再確認
Fei Chen 補充 4 個新的 Sub-issues(第二階段):
FOR-234-11:[測項] iOS — 在系統設定中關閉通知後重開,確認 UserDefaults 重讀邏輯
FOR-234-12:[測項] iOS — 首次安裝,確認預設提醒時間為 08:00(非空值)
FOR-234-13:[測項] Android 12 — 通知權限流程(舊 API)
FOR-234-14:[測項] Android 13+ — 通知權限流程(新 API)
在 Issue Comment:「三方確認完成。RD 補充的技術邊界已新增 4 個測項(FOR-234-11 至 14)。測試總計 14 個。開始測試。」
節點 6 — Testing:QA 執行測試(發現 Bug)
時間:批次視窗當天
Fei Chen 在同一個批次視窗中繼續執行測試。測試 FOR-234-5 時發現問題:設定提醒時間 09:00 → 關閉通知 → 重新開啟,設定值重置為 08:00,未保留。
Issue 狀態改為 Fix Required(V2 更新的 State 名稱,原 Ready for Fix)。
在 Issue Comment 記錄:
❌ 測試失敗 — Fei Chen — 03/07
版本:iOS Build 312
Bug:設定值在「關閉通知後重開」路徑未保留
重現步驟:設定 09:00 → 系統設定關閉通知 → 重開通知 → 看到 08:00
嚴重程度:Critical(PO Testing Notes 特別標記的重點)
截圖:[附件]
@Keith 是 UserDefaults 讀取時序的問題嗎?
因為嚴重程度 Critical,Fei Chen 即時通知 Keith(不等下個批次視窗)。Keith 在 Comment 回覆:「確認是 Bug,UserDefaults 讀取時序問題,今天修。」
節點 8 — Fix Required:Bug 修復循環
Keith 修復 UserDefaults 讀取時序,送新 PR,PR Template 更新:
Testing Notes 確認:
- [x] Y(在 Linear 補充了修復說明)
Testing Notes 技術邊界更新:
「✅ 已修復:UserDefaults 重讀路徑現在有 guard,
確認設定值在所有情境下都能保留(包含「關閉通知後重開」路徑)」
PR 合併後,Issue 狀態自動回到 Test Requested,QA 通知發出。
節點 6b — Testing:第二輪(通過)
Fei Chen 在下個批次視窗(週二 14:00-18:00)優先處理 FOR-234(Priority: High + 等待回測):
FOR-234-5 重測:✅ 設定值保留正常
全部 14 個測項:✅
父 Issue:14/14 完成
Issue 狀態改為 QA Passed。
節點 7 — 翻譯 Gate 觸發
Issue 有 [Needs Translation] Label,QA Passed 後 Automation 觸發 MKT 通知。MKT 確認後,Label 改為 [Translation Confirmed],Automation 自動將 Issue 狀態改為 Build Requested(V2 更新的 State 名稱,原 Ready for Release Build)。
節點 9-13 — Build Requested → Release Scheduled → Released
RD 包正式版,Shawn 送審,iOS Phased Release 啟動,Firebase Crashlytics 監控開始。Issue 狀態最終改為 Released,Automation 記錄時間戳。
主案例完成。
場景 A:Hotfix 緊急應對走查
情境設定:Forest App v5.8.0 上線後第 3 天,Firebase Crashlytics 的 Alert 在 Slack release-monitor 出現,顯示 Crash-free session rate 已降至 97.2%(低於 PO 的 P0 判定參考閾值 99.0%)。現在是週三上午 10:15。
10:15 — Firebase Alert 觸發,#release-monitor 出現警告
Shawn 正在處理下一個版本的 Issue,突然看到 Slack release-monitor 出現紅色通知:
🚨 Firebase Crashlytics Alert
App: Forest (iOS)
Crash-free session rate: 97.2% (過去 1 小時)
參考閾值: 99.0%
Crash Group 連結: [連結]
Shawn 的第一個動作不是自己判斷,而是立刻 DM Sherridy 和 David:「Firebase Alert 觸發,Crash-free 97.2%,已低於 99.0%。你們怎麼看?」
10:18 — David 判定 P0,授權 Hotfix
Sherridy 打開 Firebase Crashlytics,確認 Alert 是真實的(不是數據波動)。她找到 Crash Group——問題出在 iOS 通知設定功能的一條特殊路徑。
她 DM David:「Crash-free 97.2%,已確認是真實 Crash,來源是通知設定功能。你判斷是 P0 Bug 嗎?需要啟動 Hotfix?」
David 立刻回覆:「確認是 P0,授權啟動 Hotfix。指派 Keith。」
Sherridy 在 release-hotfix 發 Hotfix 啟動通知:
🚨 Hotfix 啟動通知
觸發原因:Firebase Crashlytics Alert
Crash-free session rate:97.2%(PO P0 判定參考閾值:99.0%)
Alert 時間:10:15
PO 授權:David 判定 P0 Bug 並授權
指派 RD:Keith
當前版本:v5.8.0(Hotfix 版本:v5.8.1)
@Keith 請立即查看 Firebase Crashlytics,Crash Group 連結已 DM 給你。
MTTR 計時從 10:15 開始。
10:20 — Sherridy 在 Linear 建立 Hotfix Issue
Linear → Issues → New Issue
Title:[Hotfix] v5.8.1 — 通知設定功能 Crash (iOS)
Labels:[Hotfix] + P0 + iOS
Assignee:Keith
Priority:Urgent
Description:
觸發時間:10:15
觸發原因:Crash-free rate 97.2%(閾值 98.5%)
Firebase Crash Group:[連結]
目標版本:v5.8.1(Patch Release)
MTTR 目標:Android 2-4 小時 / iOS 24-48 小時(App Store 審核)
@Keith 請在此 Issue 更新修復進度。
@Fei Chen 修復完成後需要即時快速回歸,請打破正常批次視窗。
同時通知 Fei Chen:「Hotfix Issue FOR-XXX,需要即時 QA,修復完成後我會通知你。」
10:22 — Keith 定位 Crash 源頭
Keith 收到 Hotfix Issue 通知,打開 Firebase Crashlytics。Crash Group 顯示問題集中在 iOS 16.x 以下的裝置,特定路徑下的 UserDefaults 讀取會觸發 nil pointer exception。
Keith 在 Hotfix Issue Comment 更新:「Crash 原因確認:iOS 15-16 上的 UserDefaults 讀取路徑沒有 nil check,某些舊裝置升級後設定值為 nil,導致 crash。預計修復時間:2 小時。」
Keith 立刻建立 hotfix 分支:
git checkout main
git pull origin main
git checkout -b hotfix/v5.8.1-notification-nil-crash
12:30 — Keith 完成修復,送 PR
Keith 的修復範圍最小化:只補上 nil check 和 fallback 邏輯,不順便改其他東西。
PR 說明:
Hotfix: FOR-XXX [Hotfix] 通知設定 nil pointer fix
修復:iOS UserDefaults 讀取路徑加入 nil check,fallback 到預設值 08:00
影響範圍:只影響通知設定的讀取邏輯,最小化改動
Review:只需 Ezou(RD Lead)代碼審查,不需要 PO Review
Ezou 完成快速 Code Review,PR 合併到 hotfix/v5.8.1 分支。Keith 在 Hotfix Issue Comment 更新:「修復 PR 已合併。@Fei Chen 請開始快速回歸。Android 無需 Hotfix(此問題為 iOS 特定)。」
12:35 — Fei Chen 開始快速回歸測試
Fei Chen 打開 Hotfix Issue,確認修復範圍。她使用核心功能 Checklist(2 小時內完成):
核心功能 Checklist:
□ App 啟動不崩潰 ✅
□ 主畫面正常顯示 ✅
□ 計時功能(開始 / 暫停 / 結束)✅
□ 訂閱購買流程 ✅
□ Forest 幣消費 ✅
Crash 修復特定測試:
□ iOS 16 以下裝置(iPhone X,iOS 15.7):
→ 進入通知設定 ✅(不崩潰)
→ 預設值顯示 08:00 ✅(nil check 生效,fallback 到預設值)
→ 修改設定值,確認保存 ✅
□ iOS 16 裝置:正常 ✅
□ iOS 17 裝置:正常 ✅
時間:12:35 - 14:10(共 95 分鐘)
Fei Chen 在 Hotfix Issue Comment 記錄:
快速回歸測試完成 — Fei Chen — 12:35-14:10
測試時長:1 小時 35 分鐘(< 2 小時目標 ✅)
核心功能 Checklist:全部通過
Crash 修復場景:iOS 15-16 上不再崩潰 ✅
結論:可以發布 Hotfix v5.8.1
14:15 — Sherridy 確認發布決策
Sherridy 看到 QA 通過報告,確認 v5.8.1 Patch Release:
[在 Hotfix Issue Comment]
「Hotfix v5.8.1 發布決策:
QA 快速回歸通過(Fei Chen,14:10)
決定:發布 v5.8.1 Patch Release
Android:不需要 Hotfix(此問題為 iOS 特定)
iOS:@Shawn 請申請 App Store Expedited Review」
14:20 — Shawn 申請 App Store Expedited Review
Shawn 登入 App Store Connect,提交 v5.8.1:
版本資訊說明(Expedited Review 申請):
「This update addresses a critical crash issue affecting users
on iOS 15-16 who have upgraded from previous versions.
Crash-free session rate has dropped to 97.2%, below our 98.5% threshold.
Firebase Crashlytics shows the crash is caused by a nil pointer exception
in the notification settings UserDefaults read path.
We respectfully request expedited review to protect user experience.」
Shawn 在 Hotfix Issue Comment 記錄:「App Store Expedited Review 已申請 — 14:20。預計 24-48 小時完成審核。持續監控 Firebase Crashlytics。」
隔天 11:30 — iOS v5.8.1 審核通過,發布
App Store 審核通過,Shawn 啟動 Phased Release。在 Hotfix Issue Comment 記錄:
Hotfix v5.8.1 Released — 隔天 11:30
iOS:App Store 審核通過,Phased Release 已啟動
Android:不需要 Hotfix
MTTR 計算:
Firebase Alert 觸發:週三 10:15
Hotfix Released(iOS):週四 11:30
MTTR:25 小時 15 分鐘(含 App Store 審核時間)
@Sherridy 下次 Sprint Retrospective 中討論 Crash 根因,
納入 iOS 15-16 的 UserDefaults nil check 到回歸測試 Checklist。
機制設計說明
這個場景示範了幾個設計決策:
Hotfix 觸發條件的明確化:97.2% 遠低於 PO P0 判定參考閾值 99.0%,讓 David 能快速判斷為 P0 Bug。觸發由 PO 判定,讓 Sherridy 不需要獨自承擔「要不要啟動 Hotfix」的決策壓力。
授權人的設計:PO(David 或 Ezou)其一即可判定並授權,不需要兩人都同意。Hotfix 緊急情況需要快速決策,多人授權要求會拖延 MTTR。
MTTR 計時起點的明確化:從 Firebase Alert 觸發時開始(10:15),不是從「有人注意到」或「Sherridy 確認」的時間開始。這讓 MTTR 反映真實的用戶影響時間,而非內部反應時間。
Android vs iOS 的非對稱處理:Android 不需要 Hotfix 時,就不做 Android Hotfix。不因為「統一發布」而強制要求兩個平台同步 Hotfix。
快速回歸的 2 小時目標:這不是「測完所有功能」,而是「確認核心功能不崩潰 + 修復場景不再復現」。Hotfix 的 QA 目標是品質底線保護,不是完整品質驗證。
場景 B:掉車 SOP 去污名化演練(旁白版)
情境設定:Month 2 的第一次 Feature Freeze 即將到來(03/08)。Sherridy 在每週三的風險掃描中,注意到 Keith 的 iOS 功能(FOR-257「專注音樂背景播放」)還在 In Development,距離 Freeze 只剩 2 天。這是 Forest App 導入 Release Train 後的第一次掉車。
週三下午 15:00 — Sherridy 的掉車風險掃描
Sherridy 打開 Linear,用 Board View 過濾 v5.8.0 Project 中 In Development 的 Issue。她看到 FOR-257 的狀態是 In Development,距 Feature Freeze 只剩 2 天。
她的內心獨白是:「這是第一次可能的掉車。Keith 剛加入團隊才 3 個月,我需要讓這件事感覺是正常的計劃決策,而不是『你讓我失望了』。」
Sherridy 沒有在 forest-release 公開詢問,她選擇先私訊 Keith:
Sherridy → Keith(Slack DM):
「FOR-257 我看到還在 In Development,距離 Freeze 還有 2 天。
你現在的進度大概到哪裡?
我想聽你的真實評估——不用給我最好的答案。」
15:20 — Keith 的回覆
Keith 猶豫了幾秒,想說「我再拼一下應該可以」,但想到 Sherridy 說的「不用給我最好的答案」,他如實回答:
Keith → Sherridy:
「說實話,iOS 的背景音頻 session 管理比我預想複雜。
現在差不多完成 70%,但剩下的 30% 是最難的部分——
AVAudioSession 的中斷處理有很多邊緣情況。
樂觀估計要 2 天,但我不確定是否能在 Freeze 前穩定到可以送 QA。
如果掉車,我可以理解。」
15:35 — Sherridy 的回應和掉車決定
Sherridy 讀完 Keith 的回覆,她的第一個反應是:「他說『我可以理解』,這說明他其實有準備好心理了,但還是希望我做決定。」
她回覆 Keith:
Sherridy → Keith:
「謝謝你的誠實評估,這是我需要的答案。
v5.8.0 版本照常發,FOR-257 進下一班列車(v5.8.1)。
你不是因為做得不好才掉車——是 AVAudioSession 比估計複雜,
這是技術上的不確定性,不是你的失誤。
我幫你在 v5.8.1 的 Planning 排優先,你繼續開發,
Freeze 後也可以繼續進行——只是這個版本不帶了。
我等一下在 <span class="tag">forest-release</span> 公告,你看到不用額外回覆。」
15:50 — Sherridy 在 Linear 執行掉車操作
Linear 操作:
1. FOR-257 加通用 [Dropped] Label
2. 在 Issue Comment 記錄:
「掉車決定
決定:FOR-257 掉車,移至 v5.8.1
原因:iOS AVAudioSession 背景中斷處理複雜度超出初始估計,
RD 評估在 Feature Freeze 前無法完成穩定的 Test Requested
功能評估:非本版本核心功能,可移至下一班
決定時間:03/06 15:50
批准:Sherridy
掉車原因:技術複雜度(AVAudioSession)
下一版規劃:v5.8.1,Planning 時優先排入
學習點:背景音頻功能的 edge case 在 Planning 估時時需加入不確定性係數
@David 請將 FOR-257 移出 v5.8.0 Project,加入 v5.8.1 Project。
[Dropped] Label 保留在 Issue 上,作為掉車記錄。」
3. 移出 v5.8.0 Project → 加入 v5.8.1 Project
4. Issue Comment 補充:「掉車自 v5.8.0,預計列入 v5.8.1」
16:00 — forest-release 去污名化公告
Sherridy → <span class="tag">forest-release</span>:
v5.8.0 列車更新
「專注音樂背景播放」(FOR-257)已移至下一班列車(v5.8.1)。
原因:iOS 背景音頻的技術實作比初始估計複雜,
移至下一班確保本版本品質和準時發布。
這不是因為 Keith 表現不好。
AVAudioSession 的 edge case 在業界都是已知難題,
把這個複雜性透明化、讓版本照常發,是正確的決定。
FOR-257 已排入 v5.8.1,下次 Planning 優先處理。
v5.8.0 繼續如期進行。
@Fei Chen @Jimmy 請繼續進行其他 Issue 的測試。
一週後 — Retrospective 中的掉車議程
在 v5.8.0 發布後一週的 Retrospective,掉車議程不是意外加進去的,是固定議程:
Retrospective 固定議程:掉車 Issue 回顧(5 分鐘)
本次掉車 Issue:FOR-257(專注音樂背景播放)
掉車原因:AVAudioSession 背景中斷處理複雜度超出初始估計
下一版規劃:v5.8.1,已優先排入 Planning
學習點討論:
Q1:Planning 估時時,背景音頻功能的技術不確定性是否可以在 Planning 時識別?
→ Keith 說:「AVAudioSession 的中斷行為文件不完整,估時時很難知道有多複雜。
下次類似的系統框架功能,我會在 Planning 時先寫一個技術 Spike,
確認框架行為再估主體開發時間。」
Q2:Freeze 前的風險掃描時機夠嗎?
→ Sherridy 說:「這次是 Freeze 前 2 天才確認,算是合理。
下次遇到系統框架的功能,可以在 Freeze 前 5 天就問一次進度。」
Q3:掉車的溝通流程感受如何?
→ Keith 說:「第一次掉車有點複雜的心情,但 Sherridy 先私訊我確認,
讓我有準備,不是在公開 Channel 才知道。這個做法很好。」
Sherridy 在 Cycle Description 補充:
「第一次掉車記錄:FOR-257 掉車自 v5.8.0。
文化觀察:RD 誠實評估了技術複雜度,掉車在 Freeze 前 2 天確認,
版本準時發出,掉車功能順利進入下一班。
這是列車文化的第一次成功執行,值得記錄。」
機制設計說明
這個場景示範了幾個設計決策:
私訊先行的設計:掉車決定的第一個動作是私訊 RD,不是在公開 Channel 宣布。這讓 RD 有心理準備,也讓 RM 有機會了解真實情況,而不是直接宣判。這個步驟在 SOP 中明確規定,不靠 RM 的個人判斷。
去污名化聲明的標準格式:#forest-release 的公告有固定格式,明確說明「這不是因為 RD 表現不好」。第一次說這句話會有點奇怪,但持續說,它就成為文化的一部分。
掉車記錄的公開性:掉車原因、學習點、下一版規劃都記錄在 Linear,包括在 Cycle Description。這讓掉車成為可見的歷史,而不是被藏起來的失敗。公開的掉車記錄反而降低污名——每個人都能看到決策脈絡。
Retrospective 固定議程:掉車 Issue 的討論不是「如果發生了才加進去」,而是每次 Retrospective 的固定議程。沒有掉車時,這個議程 5 分鐘說「本次無掉車」就結束;有掉車時,有結構的討論讓學習點可以累積。
場景 C:QA 批次視窗工作流走查
情境設定:週四下午 2 點,Fei Chen 開始她的 QA 批次視窗(14:00-18:00)。這是導入批次視窗機制的第三週,她已經習慣了這個節奏。
14:00 — 打開 Linear QA 待測 Queue 視圖
Fei Chen 打開 Linear,點選「QA 待測 Queue」視圖。視圖以 Priority 排序,她看到當前等待的 Issue:
QA 待測 Queue(週四 14:00):
Priority: High
FOR-267 [iOS] 訂閱升級流程改版(已等待 1 天)
FOR-271 [Android] 深色模式適配修復(已等待 4 小時)
Priority: Medium
FOR-263 [iOS][Android] 統計圖表重新設計(已等待 2 天)
FOR-269 [Server] API 回應時間優化(已等待 1 天)
她注意到 FOR-263 等了 2 天,但 Priority 是 Medium。她快速確認——Feature Freeze 在 3 天後,FOR-263 如果這個批次視窗測不完,下個視窗(週二)應該還來得及。先處理 High Priority。
14:05 — 處理 FOR-267(iOS 訂閱升級流程改版)
Fei Chen 打開 FOR-267,執行三個確認:
確認 A:版本號確認
TestFlight:有新 Build(Build 445)✅
確認 B:Testing Notes 三方確認
PO 初始填寫:訂閱頁面 CTA 文字變更、升級成功頁重設計 ✅ 已有測項
RD 技術邊界:Kenneth 在 PR Template 確認「Y」,在 Issue 補充了
「StoreKit 2 API 在 iOS 14 以下會 fallback,需要分版本測試」← 新增測項
Jimmy:Integration Test 尚未補充 ✅(CI 已跑完,無異常)
→ 補充 1 個新 Sub-issue:[測項] iOS 14 — 訂閱升級 StoreKit fallback 行為
測試過程順利,全部通過。Fei Chen 更新 Issue 狀態為 QA Passed。
在 Issue Comment:「✅ QA 通過 — Fei Chen — 週四 14:05-15:20。14 個測項全部通過。」
15:25 — 處理 FOR-271(Android 深色模式適配修復)
FOR-271 測試進行中,Fei Chen 在 Android 12 裝置上發現一個 Bug:深色模式下的通知圖示沒有適配,顯示黑色圖示在深色背景上(幾乎不可見)。
嚴重程度評估:Critical(影響核心 UX,且有截圖可重現)
Step 1:Issue 狀態改為 Fix Required
Step 2:在 Issue Comment 記錄:
「[Critical Bug] 測試失敗 — Fei Chen — 週四 15:30
版本:Android 5.8.0-ALPHA8
Bug:深色模式下通知圖示不可見(黑底黑圖)
重現步驟:切換深色模式 → 觸發任意通知 → 通知圖示不可見
嚴重程度:Critical(影響所有深色模式用戶的通知可見性)
截圖:[附件]
@Tolyn 是 drawable-night 資源沒有加?」
Step 3:即時 DM Tolyn:「FOR-271 Critical Bug,Linear Comment 已記錄,請查看。」
16:00 — 繼續處理隊列中的其他 Issue
Fei Chen 繼續處理 FOR-263(統計圖表重新設計),中等規模功能,預計需要 1.5 小時。她評估時間:目前 16:00,批次視窗到 18:00,剩 2 小時,可以完成。
測試 FOR-263 過程中,在 17:40 發現一個 Minor Bug(統計數字在特定 locale 下格式不正確):
嚴重程度評估:Minor(不影響核心功能)
處理方式:
Issue 狀態改為 Fix Required
在 Issue Comment 記錄 Bug 詳情(格式正常,不標 [Critical])
在下個批次視窗(週二)再做回歸測試
不立即通知 RD(Minor Bug 等 RD 正常工作節奏確認即可)
18:00 — 批次視窗結束,更新狀態
[在 Slack <span class="tag">qa-status</span> 發布]
「週四 QA 批次視窗完成(14:00-18:00)
完成的 Issue:
FOR-267 iOS 訂閱升級流程改版:QA 通過 ✅
FOR-271 Android 深色模式修復:發現 Critical Bug,Fix Required ❌
FOR-263 統計圖表重設計:發現 Minor Bug,Fix Required ❌(等修復)
待測 Queue 剩餘:
FOR-269 Server API 優化:下個視窗(週二)處理
@Sherridy FOR-271 的 Critical Bug 已即時通知 Tolyn,
他預計今晚修復。修復後我可以在週五臨時處理(不等週二視窗)。」
機制設計說明
這個場景示範了幾個設計決策:
批次視窗的優先順序邏輯:Priority High 先做,Priority Medium 後做。Feature Freeze 日期是次要排序依據——如果 Medium Issue 的 Freeze 快到了,可以手動調整優先順序。這個判斷是 Fei Chen 的,不需要 Sherridy 批准。
[Critical] Label 的打破批次設計:Critical Bug 的 Fix Required Issue,QA 可以在批次視窗外即時重測。這是由 Fei Chen 自行判斷的,不是每次都要 Sherridy 授權。Minor Bug 則正常排隊等批次視窗。
批次視窗的彈性:週四視窗發現 Critical Bug 被 RD 修復後,Fei Chen 可以在週五臨時處理,不一定要等到下個正式批次視窗(週二)。批次視窗是節奏設計,不是僵化規定。
視窗結束報告的作用:在 qa-status 更新,讓 Sherridy 知道當前 QA 狀態,不需要主動詢問。這是 RM 的掃描成本降低設計。
場景 D:String Freeze 走查
情境設定:Month 1 末,v5.0.0 版本進入最後 2 週。Sherridy 準備執行第一次 String Freeze——這是 Forest App 第一次有明確的「文字截止點」。
週一上午 9:00 — Sherridy 建立 String Freeze Milestone
Sherridy 打開 Linear,進入 v5.0.0 Project,建立新 Milestone:
名稱:String Freeze
日期:週三(Freeze 日期,Feature Freeze 前 7 天)
說明:「所有 UI 文字(按鈕、標籤、提示訊息)不再修改。
MKT 以此日期為翻譯截止基準。
緊急修改需 RM 批准。」
在 forest-release 發布通知:
v5.0.0 String Freeze 通知
日期:本週三
String Freeze 後規則:
✅ 允許:Bug 修復、功能邏輯調整
❌ 不允許:修改任何 UI 文字
原因:MKT 翻譯需要穩定的文字基礎。
文字變動 = 翻譯重工。
@設計師 請確認所有設計稿的 UI 文字已定稿。
@Shawn 請確認所有 Issue AC 中的 UI 文字已最終確認。
@MKT 翻譯工作從本週三開始,以本週三的設計稿為基準。
週一下午 — Shawn 確認 UI 文字
Shawn 開始逐一確認所有 v5.0.0 Issue 中涉及 UI 文字的地方:
確認清單:
FOR-230 [iOS][Android] 首頁重設計:
→ 確認按鈕文字:「開始專注」「設定目標」「查看紀錄」✅
→ PO 確認:無需修改
FOR-235 [iOS] 訂閱頁改版:
→ 確認升級文案:「開始 7 天免費試用」「選擇方案」「繼續」✅
→ PO 確認:無需修改
FOR-241 [Android] 設定頁重整:
→ Shawn 看到設定頁有一個按鈕文字「儲存偏好設定」
→ 他認為「儲存設定」更簡潔,但這是美化,不是必要修改
→ 決定:String Freeze 不申請緊急修改,下個版本優化
Shawn 在 forest-release 回覆:「✅ String Freeze 確認完成。所有 UI 文字在週一下午定稿,無需緊急修改。MKT 可以開始翻譯。」
週三——String Freeze 生效
String Freeze 在週三生效。設計師在 Figma 的 v5.0.0 設計稿上標注「String Freeze — 03/xx — 文字已鎖定」。
週四 — RD 發現需要修改文字
Kenneth(Android RD)在開發 FOR-241 設定頁時,發現一個按鈕的文字有功能性問題:按鈕文字是「確認」,但功能是「取消訂閱」,容易讓用戶誤操作。
他在 FOR-241 Issue Comment 留言,然後 DM Sherridy:
Kenneth → Sherridy(Slack DM):
「String Freeze 申請
Issue:FOR-241
原文字:「確認」
新文字:「取消訂閱」
原因:原文字會讓用戶誤以為在確認操作,
實際上是在確認取消訂閱,功能語意不正確
影響翻譯語言數:8 種」
Sherridy 評估:這是功能正確性問題(不是「文字更好看」),批准修改:
Sherridy → Kenneth:
「批准。取消訂閱流程的文字語意影響功能理解,
這是功能正確性問題,符合例外條件。
請通知 MKT 需要重譯「取消訂閱」的 8 種語言版本,
給他們預計 2 天的重譯時間。
如果 MKT 說時間不夠,我再評估是否可以延後 String Freeze 截止。」
Sherridy 在 FOR-241 Issue Comment 記錄批准決定。MKT 確認 2 天可以完成。
機制設計說明
這個場景示範了幾個設計決策:
String Freeze 的文化目的是「讓截止點是真的」:Forest App 在導入 Feature Freeze 之前,先用 String Freeze 建立「截止點是真實的、不可輕易延展的」的文化認知。String Freeze 的情緒阻力低(沒有人會因為 UI 文字截止而強烈抵抗),但它建立的文化認知可以轉移到 Feature Freeze。
例外申請的過濾設計:「文字更好看」不構成 String Freeze 例外,「功能語意不正確」構成。這個過濾條件明確,讓 Sherridy 批准例外時有原則可循,不是每次都需要主觀判斷。
PO 的 String Freeze 角色:Shawn 在 String Freeze 前主動確認所有 UI 文字,不是等到 Freeze 後才發現有問題。這個主動確認動作讓 String Freeze 真正生效,而不是形式上的截止。
第一次 String Freeze 的文化信號:在 Figma 設計稿上標注「String Freeze 已鎖定」,讓文字截止在設計工具層面可見。這個視覺標記讓所有人——包括設計師、RD、PO——都知道這是真實的截止點。
相關文件:06-角色視角指南(統整版V2) | 08-現況評估與下一步(統整版V2)
linear 導入計劃 案例 Forest release-management 統整版-v2 Hotfix 掉車SOP 批次視窗 StringFreeze