adventure-table

P3 — 實作規格

Phase:P3 — Exploration + Roll + AI
本文件只定義 P3 各 Subphase 完成後什麼必須成立。具體 DB schema、API、module、MCP transport、event delivery 與 permission wiring 放在同目錄的 開發設計方針.md;自動/人工驗收與 closeout evidence 放在 測試指南.md

最後更新:2026-09-08


1. P3 定位

P2 已把 Web 的 Room → Campaign → Roster → Seat → Lobby → Session 全鏈路做成可靠的 Server State:Session Start 時會固定本場 DM Controller 與 Player Seat 的 Active Character,支援 Late Join、End、Abandon、Resume,並保證同一 Character 不會同時被兩個 active Session 使用。

P3 是第一個真正把 active Session 變成可跑 Exploration 的桌面 的 Phase。P3 關門後,真人與外部 AI 必須能在同一場 Session 中:

P3 不是 Combat Phase。Quick Combat 留給 P4,Tactical Combat 留給 P5。P3 也不建立 Adventure Definition / Campaign Runtime(P6),不建立完整跨 Session Timeline、Snapshot / Restore、broader Export(P7)。

P3 的產品硬邊界:

  1. Server authoritative。 Human UI 與 AI Tool 最後進同一套 table action / roll / permission logic。
  2. AI 是正式 Actor,不是聊天 Bot。 AI 的能力由 Seat Role + Controller scope 決定,不因為是 AI 就取得額外權限。
  3. 秘密由 Server 過濾。 DM-only、secret DC、private event 不得先送到不該看的 client 再靠 UI / prompt 隱藏。
  4. 真人 DM 可繼續靠嘴巴跑團。 Scene、NPC、Quest、Interactable 等結構化資料在 P3 都不能變成 Exploration 的前置條件。
  5. P3 的 durable session history 只服務當場玩法與 reconnect。 完整 Timeline / 搜尋 / Snapshot / Restore 仍屬 P7。
  6. 網站本身不接 LLM API。 外部 AI 透過 MCP / Site Tools 類 structured tool transport 連入;P3 至少正式交付一條可由真實外部 AI client 使用的 MCP 入口。
  7. Standalone 永久不進 P3。 M03 standalone 仍只有 Character-first 能力,不建立 Room / Session / Exploration / AI tables 或 routes。

2. P3 固定 Subphase

P3 固定拆成六個可獨立實作、驗證與 commit 的 Subphases:

P3-A — Session Table Runtime & Event Stream
↓
P3-B — Exploration, Chat & Actions
↓
P3-C — Roll, Check & PendingAction
↓
P3-D — AI Controller, Scoped Token & Handoff
↓
P3-E — AI Tool Surface & Event Delivery
↓
P3-F — Full P3 Integration & Closeout

三份 P3 文件必須使用完全一致的名稱與順序。

不得在 P3-A 順手做 Chat UI;不得在 P3-C 先做 P4 Combat;不得在 P3-E 因 AI DM 需要 context 就提前建立 P6 Adventure Runtime;不得為了 event history 提前做 P7 的完整 Timeline / Snapshot。


3. P2 → P3 必須承接的既有真實邊界

P3 不重造以下 P2 能力:

P3 新的 GameAction / table write permission 必須擴充既有 active Session scope,而不是另外做一套「AI 權限」或「桌內 Character write」判斷。

但 P2 現行 caller identity 與 Session lifecycle authorization 實際上是 Human-only:既有 Room access session、current-DM 判斷與 live Character write scope 都不能直接代表 AI controller。P3 因此必須把桌內 gameplay caller 收斂成單一 TableActorContext/等價 typed actor context,再由 Human Room access 或 AI controller grant 各自 resolve 進來;不得替 AI 偽造 RoomAccessAuthority,也不得在 MCP tool 旁邊另做一套授權。

這個 migration 的產品不變量是:

P3 若新增 multiplayer capability,route protection 與 /api/meta capability 宣告必須同一 Subphase 同步交付,不能再發生 route 已要求 capability、Web 卻沒宣告而整頁不可達的 P2-F 缺陷。


4. P3 的 Session Table Runtime 邊界

active Session 在 P3 起除了 P2 的 participant identity,還有一份當前桌面 runtime truth。它必須能在 browser reload、Human reconnect、AI reconnect、server process restart之後重新取得,而不依賴舊 React state、舊 browser memory 或舊 AI conversation memory。

P3 runtime 至少要能恢復:

P3 不把上述資料包成一份會與 canonical tables diverge 的大 JSON snapshot。Resume 仍由 Server 讀取 canonical truth 後組合。

Session End / Abandon 後,P3 已 commit 的 session data 不刪除;它會成為未來 P7 Timeline / export 的來源之一,但 P3 本身不提供跨 Session history browser、全文搜尋、Snapshot / Restore 或 Undo。


P3-A — Session Table Runtime & Event Stream

目標

建立所有 P3 功能共用的 durable in-session runtime / event substrate,讓 browser 與 AI 都能用同一個 ordered stream 取得「自某個 revision / sequence 之後發生了什麼」,並能在 restart 後繼續。

完成後必須為真

  1. 每個 active / historical Session 有自己的 table-runtime namespace;Room A / Session A 永遠讀不到 Room B / Session B 的 runtime。
  2. Server 對每場 Session 提供單調遞增、可持久化的 event sequence;同一已 commit event 不會因 retry 產生兩個不同順序版本。
  3. event 至少能表達 public、DM-only、actor/roller+DM、指定 Seat private audience;visibility 在 Server query / projection 階段過濾。
  4. caller 只能取得自己有權看到的 event;直接猜 event id / sequence 不得繞過 visibility。
  5. browser 初次進 Session 先取得 Resume / current runtime truth,之後用 incremental event feed 更新;不得高頻重新抓完整 SessionResumeService 當即時同步方案。
  6. reconnect 可以帶 after_seq / 等價 cursor 只補缺的 event;cursor 太舊或資料不可用時可以安全 fallback 到完整 current-state resume。
  7. server restart 後 event order、runtime revision 與 pending truth 不重置、不倒退。
  8. active Session 的新 runtime write 必須確認 caller 仍屬於該 Session 的合法 controller / participant scope。
  9. event wait / long-poll 必須使用不佔住同步 worker 的 async request path;等待期間不得持有 SQLAlchemy connection / transaction。Process-local notifier只能負責 wake-up,wake / timeout後仍以短 DB recheck + durable cursor為真。
  10. 多個 idle waiter存在時,一般 DB-backed Session/event read/write仍必須可完成;client cancellation / timeout必須釋放 waiter resource,不能靠把 timeout縮短來掩蓋 starvation。
  11. P3-A 不建立 Chat、Roll、AI token 等上層產品行為,只交付它們可依賴的 substrate 與最小 diagnostics。
  12. P3-A 不把 P7 的完整 Timeline UX、跨 Session history search、Snapshot / Restore 搬進來。
  13. 若 Session 頁需要提高同步頻率,必須先解除 P2 closeout 記錄的 Resume / Lobby N+1 高頻風險;不能用更短輪詢週期放大既有 N+1。
  14. Web capability 新增 table-runtime / event 能力時,Standalone 同能力必須維持 false / unavailable。

P3-B — Exploration, Chat & Actions

目標

把 P2 的 Session page 變成真正可用的 Exploration table:Main Stage 是世界舞台,Chat 是桌上人物與玩家說話,兩者分離;真人不需要先建 Scene / NPC / Quest 才能描述行動。

完成後必須為真

  1. Session UI 有 Main Stage、右側 Chat / Dice / Log 區域與桌面角色摘要;既有 Player Card / layout 原則與 規格企劃.md 一致。
  2. Main Stage 支援:Text only、Image only、Image + Text、Clear。
  3. P3 提供最小 Room-scoped Stage image upload / replacement;圖片可被目前 Session Stage reference,Room Hard Delete 會一併清掉。
  4. Stage image 能力只服務「目前舞台」;P3 不做 Asset Library、folder/tag、Scene entity、Adventure section、Map management。
  5. Active Session 的 Stage 內容由本場 current DM Controller修改;持 DM Key 但不是本場 DM Controller者不能改桌上 Stage。
  6. Exploration input 至少支援:Character Dialogue、Action、OOC、Whisper DM;DM 另可送 Narration。
  7. Slash command 必須完整承接產品規格:/action/search/whisper/ooc 在 P3-B 轉成同一 typed Exploration input;/check 的正式 ownership 在 P3-C。Slash command不得形成第二套 business endpoint / persistence model。
  8. /search 只是一般 Exploration Action 的語意捷徑,不會自動選 Investigation / Perception、不會自動建立 RollRequest;是否需要 Check、用什麼 Skill / DC仍由 current DM裁定。
  9. Character Dialogue / Action 必須綁合法 Seat / Active Character context;一個 Human 同時控制多個 Player Seat 時必須能明確選擇是哪隻角色發言/行動。
  10. current DM 可代理任意 Player Seat執行一般 Player gameplay action。 代理走與該 Seat controller相同的 Player action / rules validation,不是 DM Direct Edit,不需要事前授權,也不改變 Seat Controller。
  11. DM proxy 必須保存實際 acting DM identity與被代理 subject Seat / Active Character,之後 event / audit / P7 Timeline可辨認「DM 代 Mira 行動」,不能記成 Mira controller自己操作。
  12. DM proxy至少涵蓋 P3-B 的 Character Dialogue / Action,以及後續 P3-C 的 roll /合法 Current State action;Seat目前是 Human、AI、Offline都不影響 current DM代理權。
  13. Whisper DM 只對 sender 與 current DM 可見;其他 Player / AI Player 的 event feed 根本不含該內容。
  14. Exploration 不依 message arrival timestamp 強制 fiction turn order;DM 保留敘事排序與裁定權。
  15. P3-B 的 Action 可以是自由文字 action intent;需要正式 pending / roll lifecycle 的 action 由 P3-C 接手。
  16. browser reload / reconnect 後 Stage 與 Session 內已 commit 的訊息仍存在;不得只存在前端 local state。
  17. 新增 UI copy、error、aria label 同 Subphase 提供 zh-TW / en,並進既有 hardcoded-copy / locale parity gate。
  18. P3-B 不做 Point-and-Click 動詞選單、Exploration grid、MMO-style current_scene_id、Fog of War、Vision / LOS。

P3-C — Roll, Check & PendingAction

目標

建立正式 Roll / Check lifecycle,以及需要等待 roll 或 DM 處理的 PendingAction。正式骰子由 Server authoritative;Secret Check 的秘密由 Server 保護。

完成後必須為真

  1. 正式 roll 有可持久化 identity,能區分 RollGroup、RollRequest、RollResult;reload / reconnect 不會失去 pending request。
  2. DM 可從 Player Action 或 DM Toolbar 建立 Request Check。
  3. Request Check 至少支援:Target(一人、多角色、Party)、Check Type(Ability / Skill / Saving Throw / 其他正式 Roll)、Ability / Skill、optional DC、Normal / Advantage / Disadvantage、optional ±N、visibility。
  4. Group Check 使用同一 RollGroup 管多個 RollRequest,UI 能顯示 Waiting / Rolled / Result;最終 fiction result 仍由 DM 判定。
  5. Server roll 產生 raw die、採用 die、modifier、total 與 source;AI 不得自行捏造一個 total 當正式結果。
  6. 支援 formal physical dice input,但必須提交 raw die(以及必要的 advantage/disadvantage 多顆 raw dice),不能只輸入 final total。
  7. Quick Dice 是獨立 convenience roll;它可以被記錄與顯示,但不得自動完成某個 pending formal RollRequest
  8. Roll visibility 至少支援 publicroller+DMdm-only;secret DC 與 dm-only result 不送 Player / AI Player。
  9. 該 RollRequest 的合法 Player controller或 current DM proxy都可完成 formal request;current DM代理時使用 target Character 的規則資料計算,並保留 acting DM + subject Seat audit identity。跨 Seat、跨 Session、非DM第三方、舊 controller token都不能 submit。
  10. /check 必須在 P3-C 被正式接手:Player 使用 /check只能表達 Check intent / 進入同一 Check UX,不得自行決定 secret DC或繞過 DM 建立正式裁定;current DM則可由同一 command / UX建立合法 RollRequest。
  11. formal request completion 必須具備 replay / duplicate submit 防護;同一 request 不得因雙擊或 network retry roll 兩次後挑結果。
  12. PendingAction 至少支援 pendingprocessingwaiting_for_rollresolvedcancelled,且狀態 transition 由 Server 驗證。
  13. ActionWindow 若在 P3 實作,必須只是 optional 的 PendingAction grouping / collection tool,不得把 Exploration 變成固定 turn system。
  14. Roll resolve 後可透過同一 table action service寫入合法 Character Current State;P3-C closeout至少證明 Human controller path與 current DM proxy path。service / authorization contract必須使用 typed actor / subject context,不能把 RoomAccessContext.access_session_id hardcode進新 service。P3-D 接上 AI grant後,AI 走同一 service,不另建 AI state-write path。
  15. P3 只建立完成 Exploration 所需的 transaction / atomic commit boundary;不提前交付 P7 的 generic Timeline transaction browser、Undo 或 Snapshot。
  16. Roll / PendingAction / state mutation 的 user-visible error 全部 stable code + 雙語 mapping,不顯示 raw exception。

P3-D — AI Controller, Scoped Token & Handoff

目標

把 P2 只有 Human / None 的實際 controller 流程擴充成真正可用的 AI controller,建立 revocable、Seat-scoped、Session-scoped 的 AI credential。Player 可 Human ↔ AI 接手;DM 仍遵守整場固定 controller、不做中途 Human ↔ AI 交接。

完成後必須為真

  1. Seat controller 正式支援 Human / AI / None;Controller type 與 Connection 狀態分開,AI + Offline 是合法狀態。
  2. AI identity 以 Adventure Table 自己的 scoped Seat credential / controller grant識別,不能用 OpenAI / Anthropic account、generic browser cookie 或 AI 廠牌識別。
  3. AI Join Token 是高 entropy secret,只在建立/rotate 時完整顯示;Server persistence只保存不可逆 verifier / hash或等價安全表示。
  4. AI Token scope 至少固定 Room、Campaign、Seat、Role / controller generation;一旦 grant 可操作某個 active Session gameplay,就必須綁定該 Session,不能拿上一場 Session token直接操作下一場。
  5. 未綁 Session 的 pre-session AI DM grant 必須有有限有效期,且不是永久 DM bearer credential。session_id 尚未綁定時,它只能用於取得自己被指派 DM Seat 的最小 pre-session context與 Start Session所需流程;不能讀 active Session private event、Chat/Narration、Roll、Character State或其他 gameplay runtime。
  6. pre-session AI DM grant在 TTL 到期、DM Seat controller改成 Human/None或rotate到另一AI、Seat archive/delete、Campaign進入 completed/archived、Room被刪除或Owner明確revoke時必須失效;成功 Start 後才轉成該 Session 的固定 controller credential並受 Session End/Abandon lifecycle約束。
  7. AI 永遠不取得 Owner Key / Owner authority;AI DM 的 gameplay DM 權限不等於 Room destructive owner權限。
  8. Human Player 可對自己目前控制的 Player Seat執行 Let AI Control,產生/rotate scoped token,並把同一隻 Active Character 的 controller切到 AI;Character identity、HP、Inventory、Spell、Current State不複製。
  9. Let AI Control 可 optional 接收 Temporary Handoff Instruction。它只屬於這次 AI handoff / controller grant,不是 Character Note、Biography、Roleplay Guidance、Campaign Fact或永久 knowledge。
  10. Temporary Handoff Instruction 在同一 AI controller generation 的 reconnect後仍可由該 AI取得;Take Back Control、grant revoke、Session End或Abandon後立即失效,下一次 handoff / 下一場 Session不自動沿用。
  11. Take Back Control 的 self-service 發起者必須是當初執行 Let AI Control 的同一個仍有效 Human Room access session。 Server必須保存這個 handoff return identity;同 Room 的其他 member、相同 display name、重新登入後產生的新 access session都不能冒充原 handoff Human。
  12. 若原 handoff Human access session已遺失/revoked(例如換裝置、清 localStorage 後拿到新的 access session),P3 第一版不假裝有跨裝置持久 Human identity;不能直接 self-service Take Back。恢復控制權要走既有 Owner/DM 的 Player Seat administrative reassignment path,並在同一 lifecycle中撤銷舊 AI grant、留下 audit,再把 Seat指派給新的 Human access session。
  13. Take Back Control 或合法 administrative reassignment完成後舊 AI Token立即失效;舊 token後續 Chat、Roll、Character state write、event wait全部被 Server拒絕。
  14. Handoff 與尚在 commit 中的正式 action必須有清楚 atomic boundary;不能讓同一 action被 old controller與 new controller各 commit一次。
  15. Player controller handoff不改 Session participant / Active Character snapshot。
  16. 每個 Seat 有單調遞增的 controller epoch/等價 generation SSOT。 AI grant只保存 mint 當下的 immutable generation snapshot;每次授權除了驗 grant active/revoked,也必須驗目前 Seat仍綁該 grant且 Seat epoch與 grant generation一致。任何 controller identity改變/rotate/Take Back/administrative reassignment都使舊 generation立即 stale。
  17. DM Controller在一場 Session開始後仍固定,不支援 Human DM ↔ AI DM中途交接。
  18. P3-D 必須完成 P2 Human-only gameplay caller migration:Human access_session_id 與 AI (grant_id, generation) 都 resolve 成同一 TableActorContext/等價 typed context;Session Start、current-DM 判斷、Late Join、End、current-DM Abandon分支與 live Character write authorization都必須接受合法 Human 或 AI current controller。AI 不建立假的 Room authority,Owner Abandon escape hatch仍保留既有 Human Room authority路徑。
  19. P3 必須讓 AI DM 可以成為新 Session 的起始 DM Controller:Owner在 Lobby事前把 DM Seat配置成 AI並產生 pre-session scoped credential;AI join後可以依同一 Session Start policy啟動該場。Start transaction把仍有效且未過期的 grant綁到新 Session,之後該 AI controller identity固定到 End / Abandon。
  20. Seat / Session / Participant persistence必須能明確保存 AI controller grant與必要的 generation/epoch snapshot,並用 DB constraint區分 Human binding、AI binding、None;不能只靠 controller_kind='ai' 加上所有既有 Human access-session欄位為 NULL 來代表「某個 AI 正在控制」。
  21. Session End / Abandon 必須撤銷所有仍可操作該 Session 的 session-scoped AI grant / token generation。 End / Abandon後舊 token不能繼續 read private events、wait、Chat、Roll或 state write;下一場需要新的合法 grant。
  22. Session End / Abandon 的 token revoke必須和 Session lifecycle transition、pending close/freeze、final event與 P2 lease release處在同一可證明的 atomic lifecycle boundary;不能先 End成功再 best-effort revoke。
  23. AI DM disconnect不會自動 End Session,也不讓 Owner或另一 AI token接管;Owner仍只有既有 Abandon escape hatch。
  24. revoke / rotate / handoff / Take Back / administrative reassignment在 DB transaction與 concurrency下安全;兩個同時變更 controller的請求不能留下兩個有效 generation或讓 stale grant繼續通過授權。
  25. Human / AI reconnect後都從 Server取回目前 controller scope、Temporary Handoff Instruction(若仍有效)與可見 pending state,不依賴舊 conversation memory。
  26. P3-D 只完成 controller與 credential,不在此 Subphase 宣稱 MCP tool surface已交付;正式 external AI 使用在 P3-E驗收。

P3-E — AI Tool Surface & Event Delivery

目標

正式交付外部 AI 可使用的 structured tool surface。P3 至少有一條可由真實 MCP client連線的 production-like入口;tool handler只作 transport adapter,核心規則仍與 Human UI共用。

完成後必須為真

  1. Adventure Table 提供正式 MCP remote endpoint;P3 target以當時正式 MCP specification 2026-07-28 的 stateless Streamable HTTP形態為基準,若實作時官方 SDK有更新,只能在不改產品契約的前提下採相容版本。
  2. MCP protocol session不是遊戲 Session identity;每個 request都必須靠 Adventure Table scoped AI credential重新建立 caller scope,不能把 authorization藏在 process-local transport session。
  3. MCP Tool handler不得直接操作 repository raw fields;Human UI與 MCP tool最後都呼叫同一 domain/application service。
  4. AI Player取得的 context只含 public + 自己 Seat / Character可見資料;不含 DM Notes、secret DC、dm-only result、其他 Seat private event。
  5. AI DM取得 DM role可見的 table state,但仍沒有 Owner destructive authority,且 AI DM不得修改 Player Character Build。
  6. MCP 至少提供能完成 P3玩法的工具面:取得 current table/session context、取得自己 Character context、post dialogue/action/OOC/whisper、Request Check(DM)、完成/提交 roll、quick roll、合法 Current State action、取得 pending events、等待新 event。
  7. Player AI context在有效 handoff期間必須能取得該次 Temporary Handoff Instruction;失效後不得再由舊 token或新 handoff自動讀到。
  8. get_pending_events() / wait_for_event(timeout) 或等價 tool 必須建立在 P3-A durable event stream上;timeout / reconnect後以 cursor重取,不依賴 long-lived model conversation或 process memory。
  9. wait_for_event timeout是正常結果,不是 error;client可以安全再次呼叫;實際 HTTP wait 必須沿用 P3-A async/no-DB-hold contract,MCP adapter不得重新用同步 blocking wait包一層。
  10. MCP tool response使用 stable structured result與 stable error code;不能要求 AI解析英文錯誤字串判斷控制流程。
  11. Tool catalog與 schema不能暴露不必要內部欄位,也不能提供 execute_sqlpatch_raw_state 類 escape hatch。
  12. P3-E 不提供高階 AI DM resolve_action() orchestration。 P3 AI DM使用較細粒度 Narration / Request Check / Current State action等共用服務;完整 narration + runtime world write-back + persistent facts orchestration由 P6 接手,完整 Timeline integration由 P7接手。
  13. 網站本身不呼叫 LLM API、不保存外部模型 API key、不主動喚醒 ChatGPT / Claude conversation。
  14. P3-E 必須有真實外部 MCP client evidence:至少一個受支援 client能以 AI Join Token進入一個 Player或DM Seat,讀 context、收 event、送 action並完成一個正式 roll/check流程。
  15. MCP transport失敗 / client disconnect不會破壞 Server State;重連後以 canonical state + event cursor恢復。
  16. Site Tools / future API Agent 可以後續包同一 application service;P3不要求為每一種 transport複製一份工具實作。
  17. standalone package不包含/不啟動 MCP multiplayer endpoint。

P3-F — Full P3 Integration & Closeout

目標

用真 PostgreSQL、真 browser、真 restart、真 external MCP client與完整 permission matrix證明 P3 是可跑 Exploration 的產品,而不是一組各自能通的 endpoint。

完成後必須為真

  1. Human DM + Human Player 可完成:Start Session → Stage → Dialogue / Action → Request Check → Roll → resolve / state change → reload → continue → End。
  2. Secret Check 的 DC / result在 network/API與 browser projection上都不洩漏給 Player。
  3. Group Check、多 Seat由同一 Human controller控制、Late Join後參與 Exploration 都有整合證據。
  4. current DM 代理 Human Player Seat、AI Player Seat(包含 offline AI)執行一般 Player Action / Roll /合法 Current State update都有整合證據;代理前後 Seat Controller不變,audit可辨識 acting DM與subject Seat。
  5. 五個 slash commands /action /check /search /whisper /ooc 都有對應實作與 browser / parser evidence;/search不自動roll,/check不讓Player繞過DM裁定。
  6. Player Human → AI → Human handoff在同一 Active Character上完成;Temporary Handoff Instruction可被AI在有效generation/reconnect後取得,只有原 handoff Human access session可self-service Take Back,Take Back後instruction失效且舊 AI token確實不能再操作。
  7. 另有負面/恢復證據證明:其他 Room member、相同 display name的新 access session不能 Take Back;原 handoff access session遺失時必須由 Owner/DM administrative reassignment恢復Player Seat,而且舊AI grant會被撤銷。
  8. AI DM可由Owner事前配置、使用有限 TTL的 pre-session scoped credential加入並Start一場新的 Session;未綁定時只能執行最小 pre-session/Start能力,Seat/controller/Campaign lifecycle變化或到期會使其失效,Session中不得被Human/另一AI接管。
  9. Human DM / AI DM 正常 End,以及 Owner Abandon escape path,都會撤銷該 Session全部有效 session-scoped AI token;End / Abandon後舊 token read/wait/write一律被拒絕。
  10. controller epoch/generation在每次 controller identity變更時單調演進;舊 grant即使 row仍是active,只要不再是Seat目前綁定的grant或generation不等於Seat epoch,也必須被拒絕。
  11. 真 external MCP client可取得 context、送 action、wait event、完成 formal check;不是只用 direct Python function或 mock client。
  12. browser reload、server restart之後 Stage、committed Chat / Action、PendingAction、Pending Roll、resolved Roll與有效 controller scope可正確恢復。
  13. Session End不修改 Character Current State;P2 invariant持續成立。
  14. Cross-Room / cross-Session / cross-Seat authorization matrix全綠,包含猜 UUID、猜 sequence、舊 token、revoked token、expired pre-session token與 stale controller generation。
  15. event order / duplicate submit / controller handoff race在真 PostgreSQL有 concurrency evidence。
  16. event wait在多個並發 idle waiter下不得餓死一般 DB-backed request;waiter timeout / cancellation後 resource會釋放,且等待期間不持有 DB connection / transaction。
  17. P3 新增 multiplayer tables / modules仍被 M03 standalone boundary gate禁止進 standalone schema / import graph。
  18. Web / Standalone capability雙向測試完整;P3頁面與MCP endpoint不會在 standalone channel誤開。
  19. P3 user-facing UI / errors / accessibility text都有 zh-TW / en,Session頁加入整頁 bilingual crawl / overflow / raw-key gate。
  20. Full existing P0 / P1 / M01 / M02 / M03 / P2 regression不因P3 route、state write或permission wrapper而退化,尤其 P2 Session lifecycle / late join / live character scope / controller persistence tests在 caller abstraction migration後仍全綠。
  21. P3 closeout evidence記錄 exact SHA、backend/frontend測試、PostgreSQL migration/concurrency、Playwright、standalone frozen smoke與真 MCP client smoke。
  22. P3 closeout不得宣稱已完成 P4 Combat、P6 Adventure Runtime / high-level resolve_action()或P7 Timeline / Snapshot;文件明列仍然存在的產品邊界與已知限制,包含「P2 Room access session不是跨裝置持久 Human identity」。

5. P3 明確不做

P3 不做:


6. P3 關門後的產品狀態

P3 關門後,Adventure Table 應第一次具備這條完整路徑:

Create / Enter Room
→ Character / Campaign / Lobby
→ Start Session
→ Human / AI 坐上 Seat
→ Exploration Stage + Chat / Action
→ DM可代理Player Seat處理缺席/無回應角色
→ DM Request Check
→ Server authoritative Roll
→ Pending / private event / reconnect
→ Player Human ↔ AI handoff + optional Temporary Instruction
→ Session End / Abandon revoke session AI tokens

此時已能用真人 DM 或外部 AI DM 跑非戰鬥 Exploration;下一個正常產品 Phase 是 P4 — Quick Combat