角色視角指南(統整版V2)

2026-02-23
統整初稿-v2角色視角操作手冊

角色視角指南(統整版V2)

本文件為各角色的第一人稱操作手冊,讓不同角色在每個節點都清楚「我具體要做什麼操作」。V2 在 V1 統整版基礎上新增 Hotfix SOP、QA 批次視窗機制、Testing Notes 三方確認機制,以及 String Freeze 先行設計。所有機制的工具限制均誠實說明:哪些是工具強制,哪些靠人工紀律。


快速跳轉


Sherridy(RM — 版本節奏守護者){#sherridy-rm}

我在這個計劃中的角色

「我是版本節奏的守護者。Feature Freeze 是我的核心工具,掉車決策是我的核心職責。我守護的不只是流程,而是 Forest App 用戶的使用體驗連續性。緊急情況下,我是 Hotfix 超車道的第一個啟動者。」

一個重要的認知:Duolingo 的 Release Manager 不在審批功能,而在守護「用戶期待的發布節奏」。一個延誤 2 週的版本,比一個少一個功能但準時的版本,對用戶體驗的傷害更大。Hotfix 是讓列車在發生事故後仍能有序修復的安全閥,不是常規列車的一部分。


操作一:Feature Freeze 設定(5 步驟 + Calendar 提醒)

觸發時機:每次 Planning 完成後 24 小時內

Step 1 — 工作量評估

與 Ezou(RD Lead)確認:
「這些 Issue,哪些可能在 [預估日期] 前完成 Test Requested?」

關鍵問題:
  → 哪個 Issue 的不確定性最高?
  → 有沒有外部依賴(翻譯 / 設計 / API)?
  → RD 是否有假期或風險?

Step 2 — 決定 Feature Freeze 日期

原則:

公式參考:
  Feature Freeze 日期 = Cycle 結束日 - 7 天 - [QA 估計工時]
  例:Cycle 結束在 3/14,QA 估計 3 天測試
  → Feature Freeze = 3/14 - 7 = 3/7

Step 3 — 在 Linear 設定 Milestone

操作路徑:
  Linear → Project(選擇當前版本)→ Milestones → Add Milestone

填寫內容:
  名稱:Feature Freeze
  日期:[選定日期]

Step 4 — 同步建立 Google Calendar 提醒(V2 新增):

Linear 沒有「距 Milestone 日期 N 天」的 Automation,因此需要手動設定 Calendar 提醒作為替代方案:

Google Calendar 操作:
  建立事件:「[版本號] Feature Freeze 前 2 天提醒」
  日期:Feature Freeze 日期 - 2 天
  時間:09:00
  說明:「今天起 2 天後是 Feature Freeze。
         確認所有 Issue 的進度,識別掉車風險。
         在 Linear 掃描 In Development 的 Issue。」
  設定重複:不重複(每個版本手動建)

Step 5 — 在 forest-release 公告

[在 <span class="tag">forest-release</span> 發布]
「v5.x.x Feature Freeze 日期:[日期]

Freeze 後規則:
  ✅ 允許:Bug Fix、現有功能修復
  ❌ 不允許:新 Issue 加入此版本 Project

如有功能確認無法在 Freeze 前完成,請提前告知我。
早告知 = 決定容易;晚告知 = 讓所有人措手不及。

@David 請在 Linear Project 更新 Milestone。」

完整記錄位置:Linear Project Milestone + Slack forest-release 公告 + Google Calendar 提醒


操作二:String Freeze 設定(V2 新增,Month 1 末執行)

背景:String Freeze 是 Level 3.5 的文化試水機制。在 Feature Freeze 之前先建立「有截止點且不可彈性延伸」的文化認知,讓團隊習慣截止點是真實的。String Freeze 的情緒阻力遠低於 Feature Freeze,是建立「截止文化」的最小代價起點。

觸發時機:Month 1 末的版本週期,版本進入最後 2 週時

Step 1 — 在 Linear 建立 String Freeze Milestone

操作路徑:
  Linear → Project(當前版本)→ Milestones → Add Milestone

填寫內容:
  名稱:String Freeze
  日期:[Feature Freeze 前 5-7 天]
  說明:「String Freeze 後,所有 UI 文字(按鈕、標籤、提示訊息)不再修改。
         MKT 以此日期為翻譯截止基準。
         如需緊急修改,需 RM 批准。」

Step 2 — 發全團隊通知

[在 <span class="tag">forest-release</span> 發布]
「v5.x.x String Freeze 通知

日期:[String Freeze 日期]

String Freeze 後的規則:
  ✅ 允許:Bug 修復、功能邏輯調整
  ❌ 不允許:修改任何 UI 文字(按鈕文字、系統提示、錯誤訊息)

原因:MKT 翻譯需要穩定的文字基礎。
      文字變動 = 翻譯重工 = 多國上架延誤。

@[設計師] 請確認所有設計稿的 UI 文字已定稿。
@[PO] 請確認 AC 中的 UI 文字描述已最終確認。」

Step 3 — 緊急文字變更申請流程

如果 String Freeze 後有人需要修改文字,流程如下:

申請方式:在 <span class="tag">forest-release</span> DM Sherridy
申請內容:
  「緊急文字變更申請
   Issue:FOR-XXX
   原文字:[原文]
   新文字:[新文]
   原因:[必須是功能邏輯問題,不是「文字更好看」]
   影響:需重譯語言數:[N 種]」

Sherridy 的批准原則:
  只批准影響功能使用正確性的文字修改
  「更好的 UX 文案」不構成 String Freeze 例外

操作三:掉車風險掃描(每週三執行)

觸發時機:每週三(固定習慣);Feature Freeze 前 3 天時必須執行

步驟

1. 打開 Linear → 當前版本 Project → Board View

2. 過濾:狀態為「In Development」或「Planning」的 Issue

3. 對每個 Issue 評估風險:
   高風險:距 Freeze < 5 天,且 Issue 仍在 In Development
   中風險:距 Freeze < 7 天,且 RD 未做過進度更新
   低風險:距 Freeze > 7 天,或 RD 表示進度順利

4. 高風險 Issue → 在 Issue Comment 詢問 RD(非 Slack DM):
   「@[RD 姓名] Feature Freeze 在 [日期],
    FOR-XXX 的完成可能性?
    如果這個時間點無法完成 Test Requested,請誠實評估。」

5. 在 Issue Comment 記錄評估結果:
   「掉車風險掃描 [日期]:
    RD 評估:[完成可能性]
    當前決定:繼續 / 列為掉車候選 / 確認掉車」

不可接受的做法


操作四:掉車 SOP 執行(5 步驟 + 去污名化聲明)

觸發時機:Feature Freeze 前掃描確認某 Issue 無法準時完成

Step 1 — 第一個動作:私訊 RD 確認(不在公開 Channel 宣布):

[在 Slack DM 給 RD]
「FOR-XXX 看起來在 Freeze 前無法完成。
 我想確認一下情況——你估計還差多少時間?
 這個版本如果沒有這個功能,你覺得有問題嗎?」

目的:讓 RD 感覺是在一起評估,不是被宣判掉車。
      這個步驟不在 Issue Comment,讓 RD 先有心理準備。

Step 2 — 在 Issue Comment 記錄決定(RD 確認後才公開記錄):

[在 Issue Comment 記錄]
「掉車決定

決定:FOR-XXX 掉車,移至 v5.x+1.x
原因:RD 評估在 Feature Freeze [日期] 前無法完成 Test Requested
功能評估:非本版本核心承諾,可移至下一班
決定時間:[日期 時間]
批准:Sherridy

@David 請在 Linear 將此 Issue 移出當前 Project,加入下一個 Project。
掉車原因:[一句話說明]
下一版規劃:預計列入 v5.x+1.x,Planning 時重新排入
學習點:[如有,記錄在此]」

Step 3 — 發布去污名化聲明(在 forest-release 公告,不可省略):

[在 <span class="tag">forest-release</span> 發布]
「v5.x.x 列車更新

[功能名稱](FOR-XXX)已移至下一班列車(v5.x+1.x)。

原因:RD 評估在 Feature Freeze 前無法完成測試,
      移至下一班可確保本版本品質和準時發布。

這不是因為 [RD 姓名] 表現不好。
功能掉車讓列車準時,準時的列車讓用戶信任我們。
[功能名稱] 已排入下一班,不是被取消。

v5.x.x 繼續如期進行。
@Fei Chen @Jimmy 請繼續進行其他 Issue 的測試。」

Step 4 — 確認掉車功能進入下一班 Project

在 Linear 確認:
  下一個版本 Project → 看到 FOR-XXX
  Issue 加上通用 [Dropped] Label(不是版本特定 Label)
  在 Issue Comment 補充:「掉車自 v5.x.x,預計列入 v5.x+1.x」

Step 5 — Retrospective 固定議程(發布後 1 週):

掉車 Issue 在 Retrospective 中有固定議程位置,不是臨時加入:

Retrospective 固定議程(5 分鐘):
  本次掉車 Issue 列表:[FOR-XXX, FOR-YYY...]
  每個掉車 Issue 的學習點:
    Q1:這次掉車決定夠及時嗎?什麼信號可以讓我們更早發現?
    Q2:掉車功能在下一班的進展如何?是否比預期更複雜?
    Q3:「列車不等人」的執行,有什麼感受需要說出來?

記錄:在 Linear Cycle Description 補充掉車記錄和學習點

操作五:Hotfix 授權與啟動(V2 新增)

當 Hotfix 觸發時,Sherridy 的第一個動作是:確認觸發條件是否真實成立,並在 release-hotfix 發 Hotfix 啟動通知。

觸發條件:PO 判定為 P0 Bug

PO 的 P0 判定依據包含(參考指標):

Step 1 — RM 識別觸發情況,通知 PO

[在 <span class="tag">release-monitor</span> 看到 Alert 後,RM 通知 PO]
Slack DM 給 David 或 Ezou:
  「Firebase Alert 觸發,Crash-free rate [XX%]。
   請確認是否判定為 P0 Bug,需要啟動 Hotfix?」

授權人:PO(David 或 Ezou,兩人其一即可,不需要兩人都同意)
PO 確認後立即通知 RM,不需要開會討論

Step 2 — PO 授權後,RM 在 release-hotfix 發 Hotfix 啟動通知

[在 Slack <span class="tag">release-hotfix</span> 發布]
「🚨 Hotfix 啟動通知

觸發原因:Firebase Crashlytics Alert
          Crash-free session rate:[XX%](觸發閾值:99.0%)
          Alert 時間:[時間]

PO 授權:David(或 Ezou)已判定為 P0 Bug
指派 RD:[RD 姓名](主修復)

當前版本:v5.x.x(Hotfix 版本:v5.x.x + 1 patch)

@[RD 姓名] 請立即查看 Firebase Crashlytics,
確認 Crash 源頭後在此 Channel 更新。

MTTR 計時從現在開始(Alert 觸發時間:[時間])。」

Step 3 — 在 Linear 建立 Hotfix Issue

Linear → Issues → New Issue

填寫:
  Title:[Hotfix] v5.x.x+1 — [問題簡述]
  Label:[Hotfix] + P0(優先級)+ [iOS/Android]
  Assignee:[RD 姓名]
  Priority:Urgent
  Description:
    「觸發時間:[Alert 時間]
     觸發原因:Crash-free rate [XX%](閾值 98.5%)
     Firebase Crash Group:[連結]
     目標版本:v5.x.x+1(Patch Release)
     MTTR 目標:Android 2-4 小時 / iOS 需 App Store 審核(緊急審核約 24-48 小時)

     @[RD 姓名] 請在此 Issue 更新修復進度。」

Step 4 — 確認 QA 批次視窗打破(如 Hotfix 需要即時測試):

[在 <span class="tag">release-hotfix</span> 通知 QA]
「@[QA 姓名] Hotfix Issue [FOR-XXX] 需要即時 QA,
 請打破正常批次視窗,優先處理。
 修復完成後我會通知你。」

Step 5 — 管理 Android vs iOS 的流程差異

Android:
  修復 PR 合併後 → QA 快速回歸(2 小時內)→ Google Play Console 緊急發布
  Google Play Staged Rollout 可以在 2-4 小時內完成

iOS:
  修復 PR 合併後 → QA 快速回歸(2 小時內)→ Shawn 申請 App Store Expedited Review
  App Store 緊急審核約 24-48 小時(無法保證)
  在等待期間保持 <span class="tag">release-hotfix</span> 更新

MTTR 計算:從 Firebase Alert 觸發時開始,到 Hotfix 版本 Released 為止
  (iOS 計算到 App Store 審核通過,不是申請時間)

操作六:QA 批次視窗緊急插單審批

觸發時機:有 Issue 需要在批次視窗外進行 QA 測試

判斷標準

可以插單的情況:
  ✅ Hotfix 相關 Issue(直接授權,不需要討論)
  ✅ 接近 Feature Freeze 且 Issue 已在 Test Requested 超過 1 天
  ✅ RD 在 Linear Issue 加上 [Priority: Urgent] 標記

不可以插單的情況:
  ❌ RD 希望「快點知道有沒有 Bug」(等下個批次視窗)
  ❌ 功能重要但時間不緊迫(等下個批次視窗)

操作

1. 在 Linear Issue 加 [Priority: Urgent] 標記(或 RD 已加)
2. 在 Issue Comment 說明原因:
   「緊急測試申請:[原因]
    授權:Sherridy
    批次視窗外測試授權:[日期 時間]」
3. DM 通知 QA:「FOR-XXX 已授權優先測試,
                 不需要等下個批次視窗。」

操作七:DORA + 消費者指標週期回顧

觸發時機:每個 Cycle 結束後,15 分鐘

回顧格式

[DORA 4 個指標]
1. Lead Time(平均):[天數] → 目標 ≤ 28 天
2. Deployment Frequency:本 Cycle 是否按時發布?
3. Change Failure Rate:本 Cycle 的緊急修復次數 / 總發布
4. MTTR(最近一次事件,Firebase Alert 起算):[天數] → 目標 < 3 天

[消費者 App 3 個指標]
5. Testing Notes 填寫率:[%] → 目標 > 90%
6. 掉車次數 vs 版本延誤次數:
   本 Cycle 掉車:[N] 次(健康)
   本 Cycle 版本延誤:[N] 次(不健康)
7. Crash-free session rate(最近發布版本):[%] → 目標 > 98.5%(初期閾值)

[Hotfix 特別追蹤]
8. 本月 Hotfix 次數:[N] 次
   注意:月超過 2 次是測試流程需要改善的信號,而非調整 Hotfix SOP

[Action Items]
  [指標名稱] 低於目標 → 原因分析 → 下個 Cycle 改善計劃

記錄位置:Linear Project Comment(每個版本 Project 都有一條回顧記錄)


Sherridy 的關鍵提醒

Feature Freeze 是你最重要的常規工具,Hotfix 是你的緊急工具。兩者都要熟練,但性質不同——Feature Freeze 守護的是節奏,Hotfix 守護的是品質底線。

掉車決定必須文件化。第一個動作是私訊 RD(保護心理安全),第二個動作才是公開記錄。這個順序很重要,不是形式問題。

Retrospective 的掉車議程不是「算誰的帳」,而是讓掉車成為公開學習的素材。掉車記錄在 Linear Cycle Description,不是藏起來,而是讓所有人可以學習。


RD(工程師){#rd}

我在這個計劃中的角色

「我的 PR 標題含 FOR-XXX,GitHub 自動更新 Issue 狀態。我在 PR Template 確認 Testing Notes 已補充,讓這個動作嵌入我的正常工作流程。Hotfix 時,我走精簡 Review 流程,直接從 main 切 hotfix 分支。我誠實評估完成時間,讓掉車決定早發生。」

一個重要的認知:Testing Notes 的補充不是額外工作。你在開發中寫 5 分鐘的技術邊界說明,可以省 Fei Chen 在測試時撞到邊界、回來問你、你解釋、她重測的來回——這個流程通常要 1-2 小時。Testing Notes 不是報告,是防止重複溝通的工具。


操作一:PR 標題 + Branch 命名

每次送 PR 前確認

# Branch 命名規範(正常功能)
feature/FOR-123-功能說明
fix/FOR-456-bug說明

# Hotfix Branch 命名規範(V2 新增)
hotfix/v5.x.x+1-問題說明
例:hotfix/v5.8.1-crash-notification-settings

# PR 標題格式
FOR-123 功能說明(或 Fix: FOR-456 Bug 說明)
Hotfix: FOR-XXX [Hotfix] 問題說明

GitHub 自動觸發:PR 標題含 FOR-XXX → Linear 自動將 Issue 狀態更新為 In Review


操作二:PR Template Testing Notes 確認欄位(V2 新增)

這是 V2 最重要的機制之一。PR Template 加入 Testing Notes 確認欄位,讓 RD 補充 Testing Notes 這個動作嵌入 PR Review 流程,而非依賴獨立習慣。

PR Template 中需要包含以下欄位(由 Ezou 確認 PR Template 內容):

## Testing Notes 確認

- [ ] 已更新 Linear Issue 的測試注意事項「技術邊界」欄位
      (如有新的技術邊界或邊界條件)
      → 確認:Y / N / 無更新(此功能無技術邊界需特別說明)

## Impact Scope(影響範圍)

- 本 PR 影響的功能範圍:[簡述,幫助 QA 判斷回歸測試需求]
- 是否影響現有已通過測試的功能? Y / N
  若是,建議 QA 回歸測試的範圍:[說明]

填寫說明

「Y」:我已在 Linear Issue 補充了技術邊界
「N」:我沒有補充——如果你選 N 且確實有技術邊界,這是問題所在
「無更新」:此功能沒有需要特別告知 QA 的技術邊界(適合小修小補)

重要原則:
  填 PR Template 確認欄位是提醒,不是工具強制。
  Linear 沒辦法阻止你選「N」就合併 PR。
  填「N」但確實有技術邊界,代價是 QA 測試品質降低,
  最終代價可能是 Hotfix。

操作三:開發中補充 Testing Notes(三方確認機制的 RD 環節)

V2 說明:Testing Notes 機制在 V2 中從「雙向強制(PO + QA)」升級為「三方確認機制(PO 初始填寫 + RD 開發中補充 + QA 雙重讀取)」。機制靠人工紀律支撐,不是工具強制。RD 這一環是三方中最脆弱的,因為沒有工具觸發(僅 Automation 5 無條件提醒),依靠 PR Template 確認欄位和習慣。

觸發時機:PR 送出前;或開發中發現 edge case 時(不要等到 PR 送出才記)

步驟

1. 打開 Linear Issue(PR 標題裡有 FOR-XXX)
2. 找到「測試注意事項」欄位
3. 在「技術邊界」區塊補充:

補充格式:
「[RD 補充 - 日期]
 [具體的技術邊界或特殊行為說明]」

補充範例(iOS RD)

[RD 補充 - 02/19]
iOS 16 以下不支援 UNNotificationTrigger 的新 API,
有 fallback 到舊 API。
建議 QA 在 iOS 15.x 的裝置上確認通知行為正常。

補充範例(Android RD)

[RD 補充 - 02/19]
Android 12 以上的通知需要 POST_NOTIFICATIONS 權限,
首次使用會出現系統授權彈窗。
QA 請測試:
  ① 授權後正常通知
  ② 拒絕後的 fallback 行為(App 應提示重新開啟,非靜默失敗)

操作四:iOS 手動確認標準 Comment 模板(V2 新增)

iOS 目前沒有如 Android 的自動版本號通知,需要 RD 手動在 Slack 確認版本。為了讓 QA 有一致的資訊格式,使用標準 Comment 模板:

在 Linear Issue Comment 發布(每次 iOS PR 合併到 staging 後)

[在 FOR-XXX Issue Comment 留言]
「iOS 版本確認通知

版本:Build [Build Number](TestFlight)
PR 合併時間:[時間]
功能:[Issue 標題]
TestFlight 連結:[連結,如有]

@Fei Chen 可以在 TestFlight 下載新版本測試。
如果 TestFlight 沒有看到新 Build,請 DM 通知我。」

同時在 Slack forest_ios_testcenter 發布

「[FOR-XXX] iOS 版本就緒通知
功能:[Issue 標題]
TestFlight Build:[Build Number]
@Fei Chen 請確認 TestFlight 已有新版本」

不要依賴記憶:把這個模板存在個人 Notion 或文件中,每次從模板複製,不要臨時打。


操作五:Hotfix 情境下的 RD 快速修復流程(V2 新增)

當 Hotfix 觸發時,RD 的第一個動作是:確認 Crash 源頭,在 Hotfix Issue 更新進度,並立即從 main 建立 hotfix 分支。

正常 PR 流程 vs Hotfix 精簡流程對照

步驟正常 PR 流程Hotfix 精簡流程
Branch 起點從 main 或 develop從 main(hotfix/vX.X.X)
PR ReviewRD Lead + PO Review只需 RD Lead 代碼審查(Ezou)
Testing Notes補充完整簡要說明修復內容即可
QA 測試完整測項核心功能 Checklist(2 小時內)
PO Review必須跳過(不需要)
MTTR 記錄必須記錄(在 Hotfix Issue)

Hotfix PR 步驟

1. 確認 Crash 源頭(Firebase Crashlytics → Crash Group)
   在 Hotfix Issue Comment 更新:「Crash 原因確認:[說明],
   預計修復時間:[Android X 小時 / iOS X 小時]」

2. 建立 hotfix 分支(從 main):
   git checkout main
   git pull origin main
   git checkout -b hotfix/v5.x.x+1-[問題說明]

3. 快速修復,最小化改動範圍
   原則:只修復 Crash 相關路徑,不順便改其他東西

4. 提交 PR,Reviewer 只需 Ezou(RD Lead)
   PR 說明重點:
     修復了什麼:[一句話]
     影響範圍:[最小化說明]
     測試建議:核心功能 Checklist 即可

5. PR 合併後,在 Hotfix Issue Comment 更新:
   「修復 PR 已合併,請 QA 開始快速回歸。
    Android:可直接測試 / iOS:等待 App Store 審核(已提交)」

iOS Hotfix 特別說明

iOS Hotfix 需要 App Store Expedited Review(緊急審核)。
你需要做的:
  告知 Shawn 修復已完成,請 Shawn 申請 Expedited Review
  在 Hotfix Issue 記錄:「iOS 修復完成,等待 App Store 審核」

你不需要做的:
  你不需要操作 App Store Connect(那是 Shawn 的工作)
  你只需要確保代碼合併到正確分支,TestFlight Build 完成

操作六:誠實評估掉車風險

正確的回覆方式(在 Issue Comment 記錄,非只在 Slack):

情況 A — 可以如期完成:
「預計在 Feature Freeze 前完成 Test Requested,
 目前進度:[具體描述],無阻塞。」

情況 B — 有風險,需要評估:
「目前有不確定性:[具體說明不確定的原因]。
 較樂觀估計可在 Feature Freeze 前完成,
 但如有延誤,建議提前掉車。
 建議:Sherridy 保留掉車選項。」

情況 C — 確定無法完成:
「預計在 Feature Freeze 前無法完成 Test Requested。
 原因:[具體原因]。
 建議:確認掉車,移至下一班。」

RD 的每次 PR 自我檢查清單

發 PR 前,確認:
  [ ] PR 標題含 FOR-XXX
  [ ] PR Template Testing Notes 確認欄位已填寫
      (Y / N / 無更新,並在 Issue 補充了對應的技術邊界說明)
  [ ] PR Template Impact Scope 已填寫
      (幫助 QA 判斷回歸測試範圍)
  [ ] iOS:已發送手動確認 Comment(Issue + Slack <span class="tag">forest_ios_testcenter</span>)
  [ ] Android:確認版本號會包含 -ALPHA
  [ ] Hotfix PR:確認只修復了 Crash 相關路徑,無額外改動

Fei Chen(QA — E2E + 雙重讀取){#fei-chen-qa}

我在這個計劃中的角色

「我在展測項和 Testing 時都讀取 Testing Notes,執行雙重確認。我用 Linear 的待測 Queue 視圖管理工作,在固定批次視窗集中處理測試。遇到 Hotfix,我在 2 小時內完成核心功能 Checklist。」

一個重要的認知:展測項時的 Testing Notes 是「Planning 時 PO 的視角(用戶角度)」,Test Requested 時的 Testing Notes 可能已有「RD 在開發中補充的技術視角(邊界條件)和 PR Template 確認的補充說明」,以及「Jimmy 的 Integration Test 發現(自動化邊界)」。只讀一次,你只有三分之一的資訊。


操作一:建立 QA 待測 Queue 視圖(月初一次性設定)

觸發時機:Month 2 第一週,一次性設定

在 Linear 建立 QA Dashboard 視圖

操作路徑:
  Linear → Team(Release Tracker)→ Views → Add View

視圖設定:
  名稱:「QA 待測 Queue」
  Filter:
    Status:Test Requested(等待測試)
    Assignee:Fei Chen(或 Jimmy)
  Sort:Priority(高 → 低),Due Date(近 → 遠)
  顯示欄位:Issue ID、Title、Priority、Labels(平台)、Due Date

第二個視圖:
  名稱:「QA 測試中」
  Filter:
    Status:Testing
    Assignee:Fei Chen(或 Jimmy)

每個批次視窗開始時的第一個動作:打開「QA 待測 Queue」視圖,確認當前待測 Issue 清單。


操作二:QA 批次視窗工作機制(V2 新增)

背景設計:個別 Issue 觸發進入等待池是正確的(不等 Milestone),但 QA 在純粹個別觸發模式下,會面臨頻繁的 context switching。批次視窗讓 Fei Chen 和 Jimmy 有固定的測試時間,保護認知資源。

工作節奏

每週兩個固定批次視窗(建議):
  視窗 A:週二 PM(14:00-18:00)
  視窗 B:週四 PM(14:00-18:00)

具體時間由 Fei Chen 和 Jimmy 根據實際工作節奏確認,
不硬性要求週二週四——重要的是每週有兩個固定時段。

批次視窗的工作流程

Step 1:打開「QA 待測 Queue」視圖
  確認當前所有 Test Requested Issue

Step 2:按 Priority + Due Date 排序,決定測試順序
  高優先 + 即將 Feature Freeze → 優先
  一般功能 → 正常排隊

Step 3:對每個 Issue 執行測試
  (詳見操作三:收到 Test Requested 後的確認流程)

Step 4:批次視窗結束時,在 <span class="tag">qa-status</span> 更新進度
  「週四 QA 批次:完成 [N] 個 Issue 測試
   待測 Queue 剩餘:[N] 個
   預計下個視窗(週二)處理」

視窗外收到的 Test Requested 通知

視窗外收到 Test Requested 通知時:
  → 不需要立即測試
  → Issue 自動出現在「QA 待測 Queue」視圖
  → 記錄在等待池,下個批次視窗處理

例外(打破批次的情況):
  ✅ Hotfix Issue:Sherridy 授權後即時處理
  ✅ Sherridy 在 Issue 加 [Priority: Urgent] 標記:即時處理
  ✅ 接近 Feature Freeze 且等待超過 1 天:可自行判斷提前處理

操作三:收到 Test Requested 後的確認流程

觸發時機:收到 Linear / Slack 的 Test Requested 通知後(在批次視窗中處理)

不要立即跑測試。先執行三個確認。

確認 A:版本號確認(iOS vs Android 差異)

iOS 確認方式:
  打開 TestFlight App → 確認有新的 Build
  ✅ 有新 Build = 可以開始測試
  ❌ 沒有新 Build = 在 Issue Comment 通知 RD
      「iOS TestFlight 沒有看到對應 FOR-XXX 的新 Build,
       請確認是否已上傳。測試暫停,待版本確認。」

Android 確認方式:
  確認 Slack <span class="tag">android-test</span> 通知中的版本號:
  ✅ 含 -ALPHA(如 5.8.0-ALPHA2)= 可以開始測試
  ❌ 不含 -ALPHA = 在 Issue Comment 通知 RD

確認 B:Testing Notes 三方確認(V2 升級)

打開 Issue → 重新閱讀「測試注意事項」欄位

三個來源都要看:
  → PO 的「重點觀測項目」(Planning 時填寫)
  → RD 的「技術邊界」補充(開發中 + PR Template 確認後補充)
  → Jimmy 可能補充的 Integration Test 發現

如果有新內容(展測項後才補充的):
  → 補充對應的 Sub-issue 測項
  → 在 Issue Comment 確認:
    「三方確認 — Testing Notes 更新讀取
     發現 RD 在 [日期] 補充了:[摘要]
     已新增對應測項:[Sub-issue 標題]
     Jimmy 補充(如有):[摘要]」

確認 C:功能定義仍然有效

V2 說明:Issue Template 已移除獨立的 Acceptance Criteria 欄位。QA 在此確認的是 Issue Description 中的功能定義是否在開發過程中被修改,而非獨立的「AC 欄位」。

確認 Issue Description 中的功能定義沒有在開發中被修改。
如果功能定義有調整,在 Issue Comment 說明:
  「功能定義更新確認:描述在 [日期] 由 @[修改者] 調整了 [具體項目]。
   測項依新版功能定義調整,舊版測項已標記廢棄。」

完成三個確認後,開始執行測試。


操作四:個別 Issue 測試(不等 Project 全部完成)

正確的行為

當 Issue A 進入 Test Requested:
  → 在下個批次視窗中測試 Issue A
  → 不等 Issue B、C、D 也進入 Test Requested

理由:越早發現問題,RD 修復成本越低。
      批次視窗已提供結構,不需要再「等一起批次測試」。

操作五:發現 Critical Bug 時的即時操作

觸發時機:測試中發現嚴重 Bug,不能等下個批次視窗才通知

Step 1:Issue 狀態改為「Fix Required」

Step 2:在 Issue Comment 記錄:
「[Critical Bug] 測試失敗 — Fei Chen — [日期]
 嚴重程度:Critical(影響核心功能)
 Bug 描述:[詳細說明]
 重現步驟:
   1. [步驟一]
   2. [步驟二]
 預期結果:[預期行為]
 實際結果:[實際行為]
 截圖:[附件]」

Step 3:即時通知 RD(不等批次視窗):
  在 Linear Comment 加 @[RD 姓名]
  在 Slack DM 通知:「FOR-XXX 發現 Critical Bug,
                     Linear Comment 已記錄,請立即查看。」

Step 4:在 Issue 加 [Critical] Label(此 Label 的 Fix Required Issue 不等批次視窗)

[Critical] Label 的意義:標注為 [Critical] 的 Fix Required Issue,RD 修復完成後,QA 可以打破批次視窗即時重測,不需要 Sherridy 授權。


操作六:Hotfix 情境下的快速回歸測試(V2 新增)

當 Hotfix 觸發時,Fei Chen 的第一個動作是:確認 Hotfix Issue 的修復範圍,準備核心功能 Checklist,在 2 小時內完成快速回歸。

快速回歸的核心功能 Checklist(每次 Hotfix 都執行):

Forest App 核心功能 Checklist(Hotfix 快速回歸):

基本流程:
  □ App 啟動不崩潰
  □ 主畫面正常顯示
  □ 計時功能(開始 / 暫停 / 結束)正常

付費功能(Hotfix 必測):
  □ 訂閱購買流程不崩潰
  □ 訂閱狀態正確顯示
  □ Forest 幣消費功能正常

Crash 修復特定測試:
  □ [依 Hotfix 的 Crash 場景,加入具體測試步驟]
  □ Firebase Crashlytics 同場景重現確認(測試後 5 分鐘觀察)

時間目標:2 小時內完成(Android) / 2 小時內完成(iOS,送審前確認)

快速回歸完成後

在 Hotfix Issue Comment 記錄:
「快速回歸測試完成 — Fei Chen — [日期 時間]
 測試時長:[X] 小時
 核心功能 Checklist:全部通過 / [X 項失敗]
 Crash 修復場景:已確認修復 ✅ / 仍可重現 ❌

結論:
  ✅ 可以發布 Hotfix 版本
  ❌ Crash 仍可重現,請 RD 確認」

Fei Chen 的關鍵提醒

批次視窗的設計目的是保護你的認知資源,不是限制你的工作彈性。如果某個批次視窗特別忙,下個視窗多排一些。如果 Hotfix 觸發,批次視窗立即打破。

三方確認機制(PO + RD + QA)靠人工紀律支撐。你的工作是確保讀到所有三方的 Testing Notes,特別是 RD 在 PR Template 確認後補充的技術邊界說明。

所有測試相關說明必須在 Issue Comment,Slack DM 只是即時通知的管道。


Jimmy(QA — Integration + 反向補充){#jimmy-qa}

我在這個計劃中的角色

「我的 Integration Test 發現的技術邊界,反向補充到 Issue 的 Testing Notes,讓 Fei Chen 的手動測試更準確。我也使用批次視窗機制,但我的測試主要在 CI/CD 自動化層面,批次視窗適用於手動 Integration 驗證部分。」


操作一:Integration Test 發現 Edge Case → 反向補充 Testing Notes

觸發時機:Integration Test 跑完後,發現 edge case 或異常行為時

步驟

Step 1:確認此 Edge Case 是否已在 Issue 的 Testing Notes 中

Step 2:在 Issue 的「測試注意事項 - 技術邊界」區塊補充:
  「[Jimmy - Integration Test 發現 - 日期]
   測試場景:[具體場景描述]
   發現:[測試結果 / 邊界行為]
   建議 Fei Chen 手動確認:[具體確認項目]」

Step 3:在 Issue Comment 通知 Fei Chen:
  「@Fei Chen Integration Test 新增發現,
   已更新測試注意事項的「技術邊界」欄位。
   請確認手動測試包含此場景。
   摘要:[一句話說明] FOR-XXX」

操作二:每個 Cycle 結束的 Integration Test 覆蓋率摘要

「Integration Test 摘要(Jimmy)— v5.x.x

本版本 Issue 數:[N] 個
有 Integration Test 覆蓋的:[N] 個([%]%)

本 Cycle 新增的 Testing Notes 補充:
  - FOR-XXX:補充了 [場景名稱] 的邊界行為([日期])

Crash 相關測試:
  已覆蓋的 Crash 場景:[列表]
  未覆蓋的高風險場景(建議下個 Cycle 補充):[列表]

建議:[下個 Cycle 最需要補充的測試場景]」

記錄位置:Linear Project Comment


Jimmy 的關鍵提醒

反向補充的時機決定價值:在 Fei Chen 開始手動測試之前補充,她的測試更完整。理想流程:PR 合併 → CI 跑 Integration Test → 你補充 Testing Notes → Fei Chen 確認後開始手動測試。

回測計數格式要一致,讓 RM 可以一眼看出 Bug 循環次數:「[回測 N] 問題描述」(如:「[回測 2] 通知設定在 iOS 16 上仍有問題」)。


Shawn(PO + 送審 + Crash Rate 監控){#shawn-po}

我在這個計劃中的角色

「我填寫每個 Issue 的 Testing Notes(重點觀測項目)。String Freeze 後,我確認所有 UI 文字已定稿。我送審後每天監控 Crash Rate。Hotfix 時,我負責申請 App Store Expedited Review。」


操作一:Testing Notes 初始填寫(PO 責任,三方確認機制的起點)

觸發時機:建立每個 Issue 時(Planning 時)

填寫框架

打開 Issue → 找到「測試注意事項」欄位 → 填寫「重點觀測項目」

思考框架(自問 3 個問題):
  Q1:這個功能的用戶旅程中,最可能出錯的是哪一步?
  Q2:有沒有邊界情況?(空狀態、網路異常、第一次使用、舊資料遷移)
  Q3:有沒有要特別確認的 UX 細節?(通知、動畫、狀態保持)

不可接受的填寫方式


操作二:String Freeze 後的 UI 文字確認(V2 新增)

觸發時機:收到 Sherridy 的 String Freeze 通知後

Step 1 — 確認所有規格中的 UI 文字

確認項目:
  □ 所有 Issue 的 AC 中提到的 UI 文字
  □ 所有 Figma 設計稿上的文字
  □ 系統訊息、錯誤提示、空狀態文字

確認後在 <span class="tag">forest-release</span> 回覆:
  「String Freeze 確認完成。
   所有 UI 文字已在 [日期] 前定稿。
   如有需要修改,請透過 Sherridy 申請緊急變更。」

Step 2 — 緊急文字變更的申請方式

如果 String Freeze 後發現文字必須修改:
  → DM Sherridy 提交申請(格式見操作一 String Freeze)
  → 不要直接通知翻譯人員
  → 等待 Sherridy 批准後才能修改

操作三:送審後的 Linear 更新

觸發時機:向 App Store / Google Play 送審完成後

在 Linear Project Comment 記錄:
「[版本] 已送審

iOS:[日期] 提交 App Store Review
Android:[日期] 提交 Google Play Review

Phased Release 計劃:
  iOS:上架後 7 天 Phased Release
  Android:10% → 50% → 100%(視 Crash Rate 決定時機)

Phased Release 監控開始時間:[上架日期]
監控負責人:Shawn(備援:David)」

操作四:Hotfix 情境下的 App Store Expedited Review(V2 新增)

當 Hotfix 觸發時,Shawn 的第一個動作是:確認 iOS 修復 PR 已合併,TestFlight Build 已完成,然後在 App Store Connect 申請 Expedited Review。

Step 1 — 確認修復已完成

與 RD 確認:
  □ iOS Hotfix PR 已合併到 hotfix/vX.X.X+1 分支
  □ TestFlight Build 已生成(Build Number 已知)
  □ QA 已完成快速回歸測試(Fei Chen 已在 Hotfix Issue Comment 確認)

Step 2 — 在 App Store Connect 申請 Expedited Review

登入 App Store Connect:
  1. 選擇 Forest App
  2. 提交新版本(v5.x.x+1)
  3. 在「版本資訊」中說明緊急原因:
     「This update addresses a critical crash issue affecting [X%] of users.
      Crash-free session rate has dropped to [XX%], below our threshold.
      Firebase Crashlytics reference: [連結或 Crash Group ID]
      We respectfully request expedited review.」
  4. 在「提交審核」頁面,選擇「Request Expedited Review」

注意:
  Expedited Review 不保證加快,但通常 24-48 小時
  在 Hotfix Issue Comment 記錄申請時間:
  「App Store Expedited Review 已申請 — [時間]
   提交說明:[說明摘要]
   預計審核完成:[估計時間]」

Step 3 — 等待期間的監控

在等待期間:
  繼續監控 Firebase Crashlytics(每 2-4 小時確認)
  在 <span class="tag">release-hotfix</span> 更新審核進度
  如果 Crash Rate 繼續惡化,通知 David 評估是否有其他緊急措施

操作五:Phased Release 監控(每天 7 天)

每日例行(約 7-10 分鐘)

Step 1 — Firebase Crashlytics 查看(5 分鐘)

Firebase Console → Crashlytics → 選擇 App

確認項目:
  ✅ iOS Crash-free session rate > 98.5%(初期閾值,3 個月後依數據調整)
  ✅ Android Crash-free session rate > 98.5%
  ✅ Android ANR rate < 0.2%

注意:V2 的初期閾值為 98.5%(低於 Duolingo 的 99.5%),Forest App 導入期間使用較寬鬆的閾值,Month 3 後依實際數據調整。Hotfix 觸發閾值也是 98.5%。

Step 2 — App Store 評論趨勢(2 分鐘)

關注:
  → 1 星評論是否在上架後明顯增加?
  → 評論內容是否出現「閃退」「當機」等字詞?
  → 如果是,在 Linear 記錄,並通知 David + Sherridy

Step 3 — 在 Linear Project Comment 記錄每天結果

正常情況:
「✅ Day [N] Phased Release 監控 — [日期]
 iOS Crash-free: 99.X%(✅ > 98.5%)
 Android Crash-free: 99.X%(✅ > 98.5%)
 評論趨勢:正常
 決定:繼續 Phased Release」

異常情況(Crash Rate 超過門檻):
「⚠️ Day [N] Crash Rate 異常 — [日期]
 iOS Crash-free: 97.X%(❌ 低於 98.5%)
 已通知 @David @Sherridy([通知時間])
 是否觸發 Hotfix:待 David / Ezou 確認」

Shawn 的關鍵提醒

Testing Notes 初始填寫是你在 Planning 時最重要的 5 分鐘。String Freeze 確認是你在版本後期最重要的確認動作。Hotfix 的 App Store Expedited Review 是你在緊急情況下最重要的操作——請把申請方式存在容易找到的地方,不要在緊急時才找教學。

Crash-free rate 的門檻(98.5%)是用戶體驗的底線,不是可以商量的目標。這個數字意味著每 100 個使用者中最多 1.5 個閃退,在消費者 App 中這個比例直接影響 App Store 評分和用戶留存。


快速參考表{#quick-reference}

操作負責人觸發時機記錄位置
Feature Freeze 設定(5 步驟 + Calendar 提醒)SherridyPlanning 完成後 24 小時內Linear Project Milestone + Slack forest-release + Google Calendar
String Freeze 設定(Month 1 末)Sherridy版本進入最後 2 週Linear Project Milestone + Slack forest-release
掉車風險掃描Sherridy每週三(固定);Feature Freeze 前 3 天(必須)Issue Comment
掉車 SOP 執行(5 步驟 + 去污名化)Sherridy(決策)+ David(Linear 操作)Feature Freeze 前掃描確認時Issue Comment + Slack forest-release
QA 批次視窗緊急插單審批Sherridy有 Urgent 測試需求時Issue Comment + Slack DM
DORA + 消費者 App 指標回顧Sherridy(主持)每個 Cycle 結束後Linear Project Comment
Hotfix 授權 + 啟動通知Sherridy(授權)+ David / Ezou(確認)Firebase Alert 觸發 / P0 Bug 識別Slack release-hotfix + Linear Hotfix Issue
Testing Notes 初始填寫PO(Shawn / Sherridy)建立 Issue 時(Planning)Issue 欄位
String Freeze UI 文字確認Shawn收到 String Freeze 通知後Slack forest-release 回覆
Testing Notes 技術邊界補充(三方確認)RDPR 送出前;PR Template 確認欄位填寫時Issue 欄位 + PR Template
PR Template Testing Notes 確認欄位RD每次送 PR 時GitHub PR Template
PR Template Impact ScopeRD每次送 PR 時GitHub PR Template
iOS 手動確認 Comment(標準模板)iOS RD每次 PR 合併到 staging 後Issue Comment + Slack forest_ios_testcenter
Android -ALPHA 版本號確認Android RD每次 PR 合併到 staging 後Slack 通知確認
Hotfix 快速修復 PRRDHotfix 授權後GitHub PR(hotfix/vX.X.X 分支)
Testing Notes 反向補充(Integration 發現)JimmyIntegration Test 跑完後Issue 欄位
回測計數格式([回測 N])Jimmy / Fei Chen每次 Fix Required 重測時Issue Comment
QA 待測 Queue 視圖設定Fei Chen / JimmyMonth 2 Week 1(一次性設定)Linear Views
QA 批次視窗執行Fei Chen / Jimmy每週兩個固定時段Linear Queue 視圖
Hotfix 快速回歸測試(2 小時)Fei ChenHotfix RD 修復完成後Hotfix Issue Comment
[Critical] Label 即時測試Fei ChenFix Required Issue 標注 [Critical] 後Issue Comment
App Store Expedited Review 申請ShawniOS Hotfix 修復完成後App Store Connect + Hotfix Issue Comment
送審後 Linear 記錄ShawnApp Store / Google Play 送審完成後Linear Project Comment
Phased Release 每日監控記錄Shawn上架後每天(連續 7 天)Linear Project Comment
Crash 異常通報Shawn(通報)+ David(授權 Hotfix)Firebase Crashlytics 異常時Linear Project Comment + DM

相關文件:00-導入計劃總覽(統整版V2) | 03-三個月導入路線圖(統整版V2) | 07-功能案例走查(統整版V2)

linear 角色視角 統整版-v2 操作手冊 Hotfix TestingNotes CrashRate FeatureFreeze StringFreeze 批次視窗