adventure-table

M01 — 測試指南

Phase:M01 — Multi-Source Character Content Expansion
類型:M Phase(Modification / Maintenance Phase)
A~N 是截至 2026-09-06 已完成的 baseline;M01 現為長期保持 open 的 Character Content Expansion / Maintenance track。M01-O 已拍板為 XGE / TCE Feat Expansion。本文件定義 M01-O 與未來 M01-P+ 的共通驗證原則,以及可在重大 regression / P Phase closeout重用的 cumulative Character baseline。Subphase名稱與順序必須與 實作規格.md開發設計方針.md 完全一致。

最後更新:2026-09-13


1. M01 共通驗證原則

每個新的 M01 Subphase closeout都要同時證明:

新 content / 新 rule shape 正確
AND
既有受影響功能沒有 regression

最低要求依 scope套用:

  1. Backend focused pytest green;Subphase closeout依 AGENTS.md gate擴大到當時需要的全套 backend。
  2. 影響 frontend / DTO / message / locale時,前端 unit / build / typecheck與對應 real-backend E2E green。
  3. 有 DB schema migration時,fresh DB與所有必要 legacy upgrade path都要測。
  4. Existing Character / Build Version / Current State / Inventory能讀,除非該 Subphase明確包含版本化 migration契約。
  5. 新 StableKey / source identity在 Draft reload、Character reload、server restart後不變。
  6. malformed content要 fail-fast,不能 silent skip。
  7. structural choice新增時要有 server domain test;影響 UI時要有 real-backend browser test。
  8. 重要 D&D規則用 focused assertions驗算,不只做大 JSON snapshot。
  9. 拒絕操作要 zero side effect。
  10. 新增/首次 expose user-visible rules presentation通過 M02 localization completeness / message contract。
  11. docs/ reference materialize的 content必須驗證 runtime沒有 docs/仍可正常工作。
  12. intentionally manual / deferred runtime效果必須分類,UI不能假裝已自動執行。
  13. P2+ 已存在後,新 M01若修改 shared Character contract,必須加入直接受影響的 downstream P Phase regression。
  14. 碰 Character JSON / Builder provenance / Version / State / StableKey / shared Character core時,必須加入 M03 standalone compatibility review。

不要求每個 content-only小 Subphase無差別跑整個專案所有 E2E;測試範圍由 dependency與AGENTS.md gate決定。


2. 測試層級

Layer A — Content / Schema / Registry

驗:manifest、counts、StableKey、source identity、duplicate、cross-pack refs、wrong-kind refs、typed mechanics、provenance、localization policy / completeness。

Layer B — Domain Unit Tests

依新 rule shape驗:Builder choice、grant、replacement、level/class-level gate、feat prerequisite/acquisition、spell access、resource、reconciliation、movement、Natural Armor、feature mode等 pure/domain semantics。

Layer C — API Integration

典型:

Create / Level Up / Build Edit Draft
→ Patch selections
→ Get choices / validation
→ Review
→ Confirm
→ Get Character / State / Version History

State mutation另驗 persistence與reject atomicity。

Layer D — Real-Backend Playwright

只有真正影響 UI / frontend contract的 Subphase才需要新增/重跑對應 browser flow。核心檢查:server-driven options、disabled reason、Draft revision、Review、Confirm、Sheet、reload、locale。

Windows環境依 AGENTS.md 使用 Docker/Linux web server,不走 Windows Vite託管路徑。

Layer E — Restart Persistence

每個新增 persistence rule shape做 focused restart test。不再把所有 M01 persistence驗證延後給一次性的 Final M01 Closeout。

當新 M01改動廣泛共享 schema,或後續 P Phase closeout / release需要 whole-character confidence時,使用本文件第 5 節的 cumulative restart dataset。

Layer F — Human Smoke

Human smoke由各新 Subphase自己決定,只用來驗 automation難以取代的 UX / presentation / real-use confusion,不拿人工重做 machine-verifiable inventory。

A~N既有 human gate / smoke證據是歷史 closeout evidence,不要求開始 P2前全部再跑一輪。

Layer G — Downstream P compatibility

P2之後若 M01修改 shared contract:

changed contract
→ enumerate direct downstream P consumers
→ focused regression / migration / E2E as appropriate

例如 Character identity若被 Party Roster / Seat引用,必須驗那些 references;純新增不改 schema的 spell content通常不需要重跑 Session lifecycle。

Layer H — M03 standalone compatibility

觸發條件至少包括:

驗:protected import boundary、standalone composition、必要 Web↔Standalone round trip / frozen smoke。若只新增與 exchange無關的 presentation文字,可依 diff縮小範圍。


3. 已完成 A~N 的證據定位

A~N已逐項 closeout;不要把本節當待辦。完整數字與 focused matrix查:

docs/M01/M01-B_CLOSEOUT.md
...
docs/M01/M01-M_CLOSEOUT.md
docs/M01/M01-N_CLOSEOUT.md
相關 *_AUTOMATED_STATUS.md / HUMAN_GATE.md
apps/server/tests/test_m01*.py
apps/web/e2e/m01*.spec.ts

目前 baseline已涵蓋的核心 rule shapes包括:

M01-O會擴充既有 Feat rule shapes;實作時優先重跑 M01-K的 Feat acquisition / prerequisite / structural / persistence / localization / browser focused suites,以及 M01-I Fighting Style / class option、M01-L movement/Natural Armor、M01-M ancestry variant等直接依賴測試,不複製第二套相同 regression。


4. 新 M01 Subphase Closeout Template

每個新 M01-O+ 至少在自己的測試段與 closeout evidence回答:

Scope / expected inventory: <result>
Content / schema validation: <result>
Domain legality / calculations: <result>
Persistence / versioning: <result or N/A>
Localization completeness: <result or N/A>
Runtime without docs: <result if materialized from docs>
Focused API integration: <result>
Focused Playwright: <result or N/A>
Restart persistence: <result or N/A>
Human smoke: <result or N/A + reason>
M03 standalone compatibility: <result or N/A + reason>
Downstream P compatibility: <affected phases / result / N/A>
Existing focused regression: <result>
Known manual/deferred effects: <summary>

如果一項 N/A,要有 scope理由;不能只寫「沒跑」。


5. Cumulative M01 / Character Regression Reference

本節承接原先規劃給 Full M01 Integration & Closeout 的價值,但不再是 P2前置 gate,也不代表執行後 M01會關門

5.1 何時使用

完整 cumulative regression適用:

小型 content-only M01不要機械式全跑。

5.2 Backend cumulative scope

全套 backend應涵蓋:

5.3 Migration reference

重大 migration時至少考慮:

fresh database → alembic head → app startup
legacy P1-era / pre-new-schema fixture → current head

代表資料:Fighter / Wizard / multiclass、damaged HP、Temp HP、Conditions、prepared spells、resources、modified Inventory、Version History、active Draft(若 contract允許)。

驗:old Build/State可讀、StableKeys不亂改、optional fields safe default、Version History一致。

未改 relational / persisted shape時,不為形式硬造 migration測試。

5.4 Real-backend cumulative E2E matrix

以下保留原 FC-E2E coverage作可重用 baseline label,不是「Final Closeout」:

FC-E2E-01 Pure SRD regression
FC-E2E-02 Variant Human + PHB Feat
FC-E2E-03 PHB subrace caster
FC-E2E-04 SCAG Background
FC-E2E-05 GoS Background
FC-E2E-06 Goblin / Hobgoblin
FC-E2E-07 Aasimar threshold
FC-E2E-08 Half-Elf Variant
FC-E2E-09 Dhampir Direct Create
FC-E2E-10 Dhampir Build Edit
FC-E2E-11 Artificer Lv3
FC-E2E-12 Artificer Multiclass
FC-E2E-13 Artificer Infusion
FC-E2E-14 Fighter TCE Fighting Style
FC-E2E-15 Paladin/Ranger nested Fighting Style
FC-E2E-16 Ranger Optional Feature Replacement
FC-E2E-17 Versatility / Retraining
FC-E2E-18 PHB / SCAG / XGE / TCE subclass source matrix
FC-E2E-19 Multiclass subclass threshold
FC-E2E-20 PHB Feat / Spell catalog
FC-E2E-21 M01-L race mechanics
FC-E2E-22 M01-M Tiefling / MTF State
FC-E2E-23 M01-O XGE / TCE Feats

FC-E2E-23apps/web/e2e/m01o-feats.spec.ts(O-E2E-01~06,見 §10.14)承擔;未來 P+ 新增新的獨立 rule shape時,追加 coverage label,不重編既有 01~23,下一個未使用 label 為 FC-E2E-24

不要求上述每個 label各自一個 spec file;coverage可合併,只要語意可定位。

5.5 Cumulative restart dataset

重大 persistence regression可建立:

  1. SRD-only legacy Character。
  2. Variant Human + PHB Background + PHB Feat。
  3. repeatable Feat multi-acquisition。
  4. non-Fighter Martial Adept。
  5. Half-Elf Variant。
  6. Dhampir Versioned Character。
  7. Artificer + Active Infusion。
  8. TCE Optional Feature / Fighting Style。
  9. non-SRD Subclass。
  10. multiclass + subclass。
  11. caster with PHB non-SRD spell / spellbook / prepared State。
  12. Lizardfolk / negative-modifier / SCAG subrace代表。
  13. standard Tiefling / MTF bloodline / SCAG variant代表。
  14. Winged equipped-state + Eladrin feature_modes。
  15. M01-O Feat 代表:option-pool Feat(Fighting Initiate / Eldritch Adept / Metamagic Adept)+ typed static fact(Gunner / Telepathic / Artificer Initiate)。
  16. P+新 persistence rule代表。

Restart後按當時 schema逐項比對 identity、current version、Build choices、State、resources、Inventory、content sources與Version History。

5.6 Cumulative human smoke reference

只有重大 milestone需要時,人工挑代表而不是逐 inventory重跑:

人工重點是:是否能理解、是否容易選錯、manual/deferred效果有沒有誤導;數量完整性與legality交給 automation。

5.7 Automation boundary report

重大 milestone可把既有 M01效果整理成:

Fully automated
Structured + state tracked, runtime manual
Deferred because Roll substrate missing
Deferred because Combat substrate missing
Deferred because Rest/day-clock substrate missing
Deferred because future Magic Items / Advanced Inventory missing

這是 implementation boundary,不是要求關閉 M01。


6. Magic Item deferral test

只要 Magic Items尚未正式成為新的 M01 Subphase,就確認任何 regression gate沒有偷偷要求:

Artificer既有 staged item identities只驗 valid / non-dangling與既有 regression。


7. Documentation consistency gate

每次新增 M01 Subphase時確認:


8. M01 Gate 類型差異

Historical content / human gates

M01-B、K、L、M等已完成 Subphase曾有各自 human/content gate。這些 gate證明當時 scope,不代表 M01整體封版,也不需要開始 P2前重跑。

Future M01-O+ gate

每個新的 Subphase只回答自己正式拍板的 scope是否完成,以及是否保住當時存在的受影響 baseline。

Cumulative regression

回答整個 Character baseline在重大變更/milestone下是否仍互相相容。它是 reusable quality gate,不是 M01 lifecycle的 final closeout。

因此:

Subphase closeout
!= M01 final closeout
Cumulative regression
!= M01 final closeout
M01 remains open while P2+ proceeds

9. M01-N — Character Sheet HTML Export

9.1 測試層級適用

Layer 適用 理由
A — Content / Schema / Registry N/A 不新增內容、不改 schema
B — Domain Unit Tests N/A 不改 Python domain
C — API Integration N/A 不新增 endpoint、不改 DTO
D — Real-Backend Playwright 適用 diff 觸及 apps/web 的角色卡畫面
E — Restart Persistence N/A 輸出不寫入任何持久狀態
F — Human Smoke 適用 自足與列印必須人工開檔確認
G — Downstream P compatibility N/A 不碰 shared Character contract
H — M03 standalone compatibility 適用(靜態) 確認未新增 server相依、import boundary不變

9.2 Frontend 單元測試

以角色卡輸出視圖為對象,至少涵蓋:

  1. 三段全出:輸出結果同時含屬性/法術/物品三段內容,且不受目前分頁狀態影響。
  2. 當前快照:含目前 HP、剩餘 Hit Dice/法術位/職業資源、狀態、已準備標記與物品欄。
  3. 角色配置:上述 Current State區段皆不出現;Max HP、Hit Dice總量、法術位總格數、資源容量仍出現。
  4. 角色配置的法術清單:法術存取清單完整出現,但沒有已準備標記。
  5. 角色配置的 AC:AC出現,且文件內含計算基準註記。
  6. 無互動控制:輸出結果不含 <button<input、分頁列。
  7. 自足:輸出字串含 <style,且不含 <scripthttp://https://src=
  8. 列印區塊存在:輸出字串含 @media print
  9. 兩種模式可分辨:檔名與文件開頭標明範圍與 Build Version;當前快照另含輸出時間。
  10. 雙語zh-TW / en各自產出對應語言,且不混語。

9.3 靜態檢查

9.4 E2E

角色卡畫面 diff ⇒ 依 AGENTS測試分層 gate跑該 Subphase觸及畫面對應的 E2E spec。E2E只需確認輸出入口存在、可選範圍、觸發後產生檔案;輸出檔內容的正確性由 9.2承擔,不在瀏覽器層重複驗。

執行一律走容器:cd apps/web && npm run test:e2e:docker(KI-ENV-001)。

9.5 Human smoke

自動測試無法涵蓋「檔案在別的機器上打得開」與「印出來好不好看」。人工確認:

  1. 兩種範圍各輸出一份,關掉本站前後端,直接雙擊開啟,內容正確。
  2. 瀏覽器列印預覽:不是深色底,卡片沒有被切在跨頁處,A4寬度不溢出。
  3. zh-TW / en各開一份確認語言正確。

9.6 Closeout evidence

Scope / expected inventory: 兩種輸出範圍 + 列印樣式
Content / schema validation: N/A — 不新增內容、不改 schema
Domain legality / calculations: N/A — 不改 Python domain
Persistence / versioning: N/A — 輸出不寫入任何狀態
Localization completeness: <zh-TW / en 新增文案結果>
Runtime without docs: N/A — 不從 docs materialize
Focused API integration: N/A — 不新增 endpoint、不改 DTO
Focused Playwright: <結果>
Restart persistence: N/A — 無持久狀態
Human smoke: <離線開檔 / 列印 / 雙語結果>
M03 standalone compatibility: <靜態檢查結果 — 無 server相依、import boundary未變>
Downstream P compatibility: N/A — 不碰 shared Character contract
Existing focused regression: <前端單元測試與 build結果>
Known manual/deferred effects: <PDF產生交給瀏覽器;不做歷史版本與批次輸出>

10. M01-O — XGE & TCE Feat Expansion

10.1 測試層級適用

Layer 適用 理由
A — Content / Schema / Registry 適用 新增 XGE/TCE 30 個 Feats與typed mechanics
B — Domain Unit Tests 適用 ancestry prerequisite、nested choices、retraining、spell grants、resource restriction
C — API Integration 適用 Create / Level Up / Build Edit / Review / Confirm / Version persistence
D — Real-Backend Playwright 適用 Builder Feat pool、disabled reason、nested selectors、Review / Sheet
E — Restart Persistence 適用 acquisition-linked selections / retraining / resource metadata需跨 restart保留
F — Human Smoke 可縮小 只驗複雜 nested Feat是否容易理解;inventory交給 automation
G — Downstream P compatibility 適用(focused) P2 Room Character Workspace直接承接 Builder;P3視 DTO/schema diff決定
H — M03 standalone compatibility 適用 Content Registry / StableKey / Builder / Character JSON共享

10.2 Inventory / content validation

新增 deterministic verifier與 focused tests,至少 assert:

XGE M01-O Feats = 15 / 15
TCE M01-O Feats = 15 / 15
total = 30 / 30
duplicate StableKey = 0
wrong pack provenance = 0
missing required zh-TW = 0
missing required en = 0

逐項驗:

10.3 Prerequisite resolver

至少涵蓋正/反例:

  1. Dragon Fear:Dragonborn可選;非 Dragonborn拒絕。
  2. Drow High Magic:Drow可選;High Elf不能誤過。
  3. Elven Accuracy:Elf / Half-Elf可選;Human拒絕。
  4. Prodigy:Human、Variant Human (phb2014:race:variant-human)、Half-Elf、Half-Orc皆可選;其他拒絕。Variant Human 必須靠 ancestry normalization 通過,不能假設它是 Human subrace。
  5. Squat Nimbleness:Dwarf或 Small race任一成立即可;Medium non-Dwarf拒絕。
  6. Eldritch Adept / Metamagic Adept:Spellcasting或Pact Magic任一可解鎖;沒有施法能力則拒絕。正例必須包含 subclass-granted Spellcasting:Fighter 3 Eldritch Knight 與 Rogue 3 Arcane Trickster 可選;Fighter 3 Champion、Fighter 2 尚未選 subclass 拒絕。
  7. Fighting Initiate:具任何 martial weapon proficiency即可;沒有則拒絕。
  8. Variant Human獨立 race StableKey、Half-Elf variant、Tiefling bloodline等既有 variant / replacement皆不應失去其 canonical base ancestry資格;並驗 Variant Human保留自己的 StableKey identity,不被 rewrite成 Human。

所有拒絕要驗 structured code + params,且 Draft / Build零副作用。

10.4 Structural / nested choices

至少涵蓋:

10.5 Spell-grant matrix

Focused assertions至少涵蓋:

  1. Drow High Magic固定三個 canonical spell refs、CHA、at-will / 1-LR metadata。
  2. Fey Teleportation固定 Misty Step、INT、1-SR-or-LR與正式 Sylvan language grant;Sylvan不能只出現在 description。
  3. Wood Elf Magic的 Druid cantrip selector只列合法 cantrip;Longstrider / Pass without Trace固定 grant。
  4. Artificer Initiate只列 Artificer cantrip + level-1 Artificer spell,並保留 free cast + spell-slot cast語意;其 artisan-tool choice / focus eligibility由 10.4 同時驗證。
  5. Fey Touched只允許 level-1 Divination / Enchantment;Shadow Touched只允許 level-1 Illusion / Necromancy。
  6. Fey/Shadow Touched所選 INT/WIS/CHA同時驅動 spellcasting ability,不可製造矛盾值。
  7. Telekinetic:Mage Hand已知/未知兩種 candidate Build都能得到正確 grant/augmentation metadata。
  8. Telepathic:Detect Thoughts fixed grant、free cast與 chosen casting ability正確;60 ft單向心電感應另由 10.7 驗證,不得因 spell grant通過就視為整個 Feat完成。
  9. Feat spell access不污染 class Known / Prepared或原 spell provenance。

10.6 Retraining / Version History

建立至少三組 Level Up domain / API tests:

共同 assert:

Version N保持舊 selection
Version N+1保存新 selection
content_sources穩定
reload / restart後一致
Build Edit不能被當成免費 retraining path

若既有 correction-mode Build Edit有不同明確契約,測試需證明它仍只是 correction而非一般玩家 retraining入口。

10.7 Static mechanics / resource restriction

至少驗:

10.8 Automation boundary tests

每個 30 Feats都必須有合法 automation classification。針對代表效果 assert沒有誤標 fully automated:

static analysis / test要防止 M01-O新增 P4 combat tables/services或 generic trigger DSL依賴。

10.9 API / persistence / restart

至少建立代表角色覆蓋:

  1. XGE racial feat + ability choice + static mechanic。
  2. Prodigy / Skill Expert多 nested choices。
  3. Fey Touched / Shadow Touched spell selection。
  4. Fighting Initiate / Eldritch Adept / Metamagic Adept canonical option refs。
  5. Metamagic Adept source-restricted resource contribution。
  6. Artificer Initiate artisan-tool selection + INT spell focus eligibility。
  7. Gunner firearms proficiency或Telepathic static communication fact至少一項作 typed-static representative。

走:

Draft → choices → patch → review → confirm
→ reload Character / Version History
→ restart server
→ reload again

assert acquisition id、StableKeys、selected refs、ability/spell link、tool/focus selection、typed static facts、resource metadata、content_sources與Version History不變。

若沒有 relational schema change,migration為 N/A;若實作最終新增 Alembic,則 fresh DB + legacy upgrade path升級為 mandatory。

10.10 Real-backend Playwright

M01-O focused browser至少覆蓋以下語意;可以合併到較少 spec,但每項可定位:

O-E2E-01 XGE racial prerequisite:Dragonborn可選 Dragon Hide / 錯誤 race顯示 disabled reason;Prodigy representative 要包含 Variant Human ancestry-normalization 路徑
O-E2E-02 Prodigy或Skill Expert:nested proficiency + expertise完成並在 Review/Sheet顯示
O-E2E-03 Fighting Initiate:canonical style selector、duplicate style拒絕、ASI Level Up可替換
O-E2E-04 Eldritch Adept:spellcasting gate、invocation prerequisite、下一級可替換
O-E2E-05 Fey Touched或Shadow Touched:school-filtered spell selector + ability-linked casting stat
O-E2E-06 Metamagic Adept:兩個 distinct options + 2-point restricted resource presentation + reload

至少一條 flow從 Room Character Workspace開始,證明 P2 Room-first路徑不是只在舊 global Builder fixture成立。zh-TW / en 至少各有一個代表 detail/presentation assertion;不需要把 30個 Feats逐一用 browser點完,inventory/completeness由 backend verifier負責。Artificer Initiate、Gunner、Telepathic的完整 mechanics可由 domain/API tests承擔,不要求各自再增加一條 browser journey,只要 Review/Sheet對已選 nested option與typed fact的既有 presentation contract有代表性覆蓋。

Windows完整 E2E依現行容器路徑執行,不使用已知不穩定的 Windows Vite full-suite path。

10.11 M03 standalone / downstream compatibility

M03:

P2:

P3:

10.12 Human smoke

若 automation已完整覆蓋 inventory與legality,human smoke只挑 2~3 個最複雜選擇確認 UX:

重點是 disabled reason、choice順序、Review是否看得懂,以及 deferred Combat效果有沒有被 UI誤導成「系統會自動執行」。

10.13 Closeout evidence

Scope / expected inventory: XGE 15/15 + TCE 15/15 = 30/30
Content / schema validation: <manifest / StableKey / provenance / refs / automation class>
Domain legality / calculations: <ancestry prereq / nested choices / option pools / static mechanics>
Persistence / versioning: <Create / Level Up / retraining / Version History>
Localization completeness: <zh-TW / en 30 Feats + new messages>
Runtime without docs: <pass>
Focused API integration: <result>
Focused Playwright: <O-E2E-01~06 result>
Restart persistence: <result>
Human smoke: <result or N/A + reason>
M03 standalone compatibility: <result>
Downstream P compatibility: <P2 result;P3 result/N/A reason>
Existing focused regression: <M01-I/K/L/M directly affected suites>
Known manual/deferred effects: <30 Feats automation boundary summary>

10.14 契約 ↔ 測試對照

每條 10.x 契約必須能定位到可執行的測試;本表是 closeout 時的核對清單,「尚無」即為 closeout 前必補項。Backend 檔案位於 apps/server/tests/,瀏覽器 spec 位於 apps/web/e2e/

契約 測試
10.2 Inventory / content validation scripts/verify_m01o_feat_inventory.py(由 test_m01o_inventory_script.py 包裝執行):30/30、StableKey 唯一、pack provenance、prerequisite type / automation / choice kind 白名單、dangling ref、manifest count、spell selector 至少一個候選、zh-TW / en name + data.desc.0 存在且不走 locale fallbacktest_m01o_feat_expansion.py::test_m01o_inventory_and_locale_overlay_are_registered。「移除 docs/ 後 runtime 仍正常」:test_m01o_inventory_script.py::test_runtime_does_not_read_reference_markdown(靜態掃描 app/ 無 docs/ 及暫用規則資訊字樣,動態隔離 docs/ 後 registry 載入 30 專長、_available_result 編譯、Prodigy 展開與 zh-TW / en 在地化均正常)
10.3 Prerequisite resolver test_m01o_prerequisites.py(ancestry / size / feature / proficiency / spellcasting / any_of atom,含 context-missing 與 mismatch 區分);test_m01o_feat_expansion.py::test_variant_human_counts_as_human_ancestry_for_xge_racial_feats::test_size_or_dwarf_prerequisite_and_allowed_skill_options_are_enforced::test_subclass_spellcasting_satisfies_tce_spellcasting_prerequisite::test_selecting_a_feat_with_an_unmet_origin_prerequisite_reports_a_structured_issue(選取後為 structured code + params、零副作用)。正反例:test_m01o_feat_expansion.py::test_dragon_fear_requires_dragonborn_ancestry::test_drow_high_magic_requires_drow_lineage_not_any_elf::test_elven_accuracy_accepts_elf_and_half_elf_and_rejects_human::test_fighting_initiate_rejects_a_build_without_martial_weapon_proficiency::test_race_variants_keep_their_base_ancestry_for_racial_feats(所有拒絕案例均斷言 zero side effects)
10.4 Structural / nested choices test_m01o_feat_expansion.py::test_skill_expert_grants_selected_skill_and_matching_expertise::test_artificer_initiate_grants_artificer_spells_and_selected_tool::test_typed_static_facts_land_on_the_build_and_round_trip(Artificer tool → focus eligibility)、::test_eldritch_adept_offers_the_canonical_invocation_pool_with_warlock_only_prerequisites::test_fighting_initiate_excludes_the_style_the_fighter_already_knows::test_class_fighting_style_slot_disables_the_style_a_feat_already_granted::test_superior_technique_through_fighting_initiate_exposes_its_maneuver_choice::test_metamagic_adept_grants_distinct_options_and_restricted_resource;Prodigy 四段 nested 由 O-E2E-02 走 UI。Tool identity 與重複檢查:test_m01o_feat_expansion.py::test_chef_and_poisoner_reuse_the_canonical_tool_proficiency_identity(複用 canonical tool proficiency 不造平行 identity)、::test_metamagic_adept_rejects_duplicate_metamagic_selection(重複選擇 Metamagic 發出 duplicate_choice_option 且零副作用)
10.5 Spell-grant matrix test_m01o_spell_grants.py::test_drow_high_magic_grants_three_charisma_spells_with_their_use_metadata(1)、::test_fey_teleportation_grants_misty_step_and_a_formal_sylvan_language(2)、::test_wood_elf_magic_cantrip_pool_is_druid_only_and_fixed_spells_use_wisdom(3)、test_m01o_feat_expansion.py::test_artificer_initiate_grants_artificer_spells_and_selected_tool(4)、::test_fey_touched_links_fixed_and_selected_spells_to_chosen_ability(5、6)、test_m01o_spell_grants.py::test_telekinetic_grants_mage_hand_regardless_of_prior_knowledge(7)、::test_telepathic_grants_detect_thoughts_free_cast_on_the_chosen_ability(8)、::test_feat_spell_access_does_not_pollute_class_known_or_prepared_lists(9);O-E2E-05 驗 Fey / Shadow school filter 與 casting ability
10.6 Retraining / Version History test_m01o_retraining.py::test_eldritch_adept_invocation_can_be_replaced_at_any_level_up::test_fighting_initiate_style_replacement_waits_for_an_asi_level::test_metamagic_adept_replaces_one_option_per_asi_level_up::test_build_edit_is_not_a_free_retraining_path(Version N / N+1 各自保留、content_sources 穩定);O-E2E-03 / 04 走 UI
10.7 Static mechanics / resource restriction ::test_dragon_hide_natural_armor_joins_the_unarmored_ac_candidates::test_squat_nimbleness_adds_five_feet_to_walking_speed_once::test_gunner_keeps_firearms_as_deferred_typed_fact::test_typed_static_facts_land_on_the_build_and_round_trip(Gunner firearms / Telepathic 60 ft / Artificer focus 進 feat_static_facts)、::test_metamagic_adept_grants_distinct_options_and_restricted_resourceallowed_spend_tags);test_m01o_feat_expansion.py::test_infernal_constitution_exposes_resistances_and_poison_save_advantage(目前為 Registry 層讀取)、::test_expanded_spellcasting_atom_unlocks_phb_caster_feats_for_subclass_casters(Elemental Adept / Spell Sniper / War Caster 對 Eldritch Knight / Arcane Trickster 解鎖且純 martial 拒絕);PHB Tough / Observant / Martial Adept representative regression 由 test_m01k_feats_matrix.py::test_m01k_phb_feats_build_matrix[tough]test_m01k_feats_matrix.py::test_m01k_phb_feats_build_matrix[observant]test_m01k_feats_matrix.py::test_m01k_phb_feats_build_matrix[martial-adept] 正式具名對照
10.8 Automation boundary verifier 驗 30 個 Feats 的 automation 只用允許值;::test_gunner_keeps_firearms_as_deferred_typed_facttest_m01o_automation_boundary.py::test_m01o_feats_are_not_mislabelled_as_fully_automated(全部 30 專長 automation 分類與 Poisoner ignore_poison_resistance 結構化驗證)、::test_deferred_m01o_feats_do_not_change_derived_sheet_values(15 個 deferred 專長無 static_derived_modifiers 且不靜默變更 HP/AC/速度/被動察覺與調查)、::test_m01o_content_and_domain_do_not_import_combat_or_trigger_dsl(靜態分析 content 與 domain 無 combat / trigger_dsl / TriggerRule 依賴)
10.9 API / persistence / restart test_m01o_retraining.py::test_m01o_representative_builds_survive_reload_restart_and_history:8 個代表角色(Dragon Hide、Prodigy、Fey Touched、Fighting Initiate、Eldritch Adept、Metamagic Adept、Artificer Initiate、Gunner)confirm → reload → rebind_http 重啟 → reload,snapshot 含 acquisition、spell link、resource、typed fact、content_sources、Version History。Migration:N/A(無 Alembic,feat_static_facts 為 optional JSON field)
10.10 Real-backend Playwright m01o-feats.spec.ts:O-E2E-01(Dragonborn Dragon Hide + disabled reason 文案、Variant Human Prodigy normalization)、O-E2E-02(Prodigy nested + Review grants + Sheet expertise 修正值)、O-E2E-03(class style 與 feat style 互斥文案、非 ASI 升級被拒 banner、ASI 升級替換、Version History 頁)、O-E2E-04(Eldritch Adept spellcasting gate、invocation prerequisite 文案、下一級替換)、O-E2E-05(Fey / Shadow school filter、casting ability)、O-E2E-06(chip picker 2/2、draft reload、Sheet 資源「Metamagic Adept Sorcery Points 2 / 2」)。每條皆從 Room Character Workspace 起;zh-TW / en feature chip 各有 assertion。共用 helper:e2e/support/builderUi.ts。執行:cd apps/web && npm run test:e2e:docker -- e2e/m01o-feats.spec.ts
10.11 M03 standalone / downstream test_m01o_standalone_roundtrip.py(standalone Create Gunner → export → 另一 standalone dry-run / import → re-export 相等,feat_static_facts 隨行);test_m03_import_boundary.pytest_m03b_schema_inventory.pytest_m03b_build_ref_walker.py(新 Build 欄位已登記)。P2:O-E2E 全部走 Room Character Workspace。P3:Character identity / sheet payload contract 未改,static N/A
10.12 Human smoke 2026-09-14 由使用者真人執行三類代表 Feat 通過;O-E2E-01 / 02 / 05 / 06 另有真實瀏覽器覆蓋。發現並修正 zh-TW feat kind 標籤漏譯(f3a7b18),見 M01-O_CLOSEOUT.md