adventure-table

Agent Instructions — Adventure Table

一個輕量、桌上跑團優先的 D&D 5e 2014 VTT。真人 DM 像實體跑團一樣主要靠口頭敘事,只在需要時使用網站工具;外部 AI 透過 MCP / Site Tools 正式進桌當 DM 或 Player,與真人共用同一套 Game State、規則與權限。

New Conversation Opening Check

Layer 1 — 必讀:

  1. AGENTS.md(本檔)
  2. PROJECT_BRIEF.md(當前 Phase、Roadmap、文件索引)
  3. git log --oneline -10

Layer 2 — 按任務讀對應文件/段落:

不要為了「先想完整」而提前設計後續 Phase。資料模型、API、事件、權限實作、Snapshot、Combat、Tactical 等細節,原則上等對應 Phase 再決定。

Report to user: current progress, and any issues with their scope of impact.

Layer 0 — 每個任務開工前先過這張表(不是只有開場):

任務類型 先讀
診斷 bug、分析錯誤、找根因、效能回歸 diagnose
使用者要求深入訪談/壓力測試設計,或存在無法由既有規格解決的核心產品分歧 grill-me
前端/本機 web app 驗證、UI 行為除錯、瀏覽器截圖或 console log webapp-testing

判斷任務類型是開工的第一步,不是可選項。

一般需求釐清或規格討論先查文件與程式,只問必要問題,不因此自動啟用 grill-me;純技術或一般 UX 決策仍依「設計討論的方式」處理。指定 skill 若不存在,說明限制並依本檔原則繼續可執行的工作,不假裝已讀取;若缺少完成任務必要的能力,明確回報阻礙。

文件查閱規則

AGENTS.mdPROJECT_BRIEF.md 開場整份讀。規格企劃.md 一律標題 grep 定位、只讀該段(讀到下一個同級標題為止),整份讀會被工具截斷。

不要依賴行號——行號隨編輯漂移,一律以標題或關鍵字定位。

規格企劃.md 的定位鍵是章節中文數字與 ### 小節:

grep -n "^## \\|^### " 規格企劃.md

十四個章節的對照:

找什麼 去哪章
硬原則、一句話摘要 〇 產品基線
定位、SRD / 非 SRD 內容策略
Seat / Role / Controller / 權限 / AI 接手 / DM 修改權
Room / Campaign / Session / Party Roster / Resume
Homepage / Main UI / Character Sheet / Exploration / DM Toolbar
Character Workshop / Builder / 版本 / 法術 / Temp HP / Hit Dice
Combat Engine / Quick / Tactical / Conditions / Death Save
Adventure / Campaign Runtime / AI DM write-back / Importer
NPC / Monster / Scene / Knowledge / Roll System
Timeline / GameTransaction / Snapshot
Inventory / Loot / Shop / Quest / Rest
資料生命週期 / Export / Import 十一
第一版明確不做 十二
文件維護與討論規則 十三
開發接手原則 十四

提新功能前先看第十二章。 那份清單是刻意砍掉的東西,不是還沒做的待辦。

同一 Phase 已拆出 Subphase 後,三份 Phase 文件的 Subphase 標題必須一字不差。實作或驗收某個 Subphase 時,只讀該段及必要的共用前言,例如:

grep -n "M03-B" docs/M03/實作規格.md docs/M03/開發設計方針.md docs/M03/測試指南.md

U 類例外採單檔格式,直接讀對應 docs/Uxx/Uxx-<letter>.md

文件分工與單一事實來源

同一件事只住一個地方。

住哪 放什麼
規格企劃.md 產品行為與為什麼:跑團方式、權限、規則選擇、UI 行為、明確不做
PROJECT_BRIEF.md 當前 Phase、Roadmap、Subphase 進度、下一步、文件索引
技術棧討論.md 暫時性的基礎技術選型討論:語言、Framework、DB、基本測試/部署工具
docs/Px/實作規格.md / docs/Mxx/實作規格.md 該 Phase / Subphase 完成後什麼必須為真、驗收意圖;不寫具體 DB/API
docs/Px/開發設計方針.md / docs/Mxx/開發設計方針.md 該 Phase / Subphase 的具體實作契約:資料模型、模組、API、資料流、接線、必要技術決策
docs/Px/測試指南.md / docs/Mxx/測試指南.md 該 Phase / Subphase 的自動/人工驗收流程與測試證據要求
docs/Uxx/Uxx-<letter>.md U 類單一 Subphase 的實作目標、技術設計、測試/效能驗收與 closeout 證據;不套三份文件制
SRD / 規則資料檔 所有規則內容與可調數值
待決事項.md 真正無法從既有規格推導、且會影響核心玩法/方向的未決問題

文件裡不重複抄規則數值,一律指向資料檔。

判準:如果一句話不同,DM/Player 的實際跑團方式可能就不同 → 規格企劃.md;如果是某 Phase 要做到什麼 → 該 Phase 實作規格.md;如果是怎麼實作 → 該 Phase 開發設計方針.md

Phase / Subphase 設計原則

  1. 只設計正在準備開工的 Phase。 尚未輪到的 P / M Phase 保持大 Phase 狀態,不提前設計其 schema / API / module;可以記錄已知的跨 Phase 相容要求(例如 P0 要求 Character 資料模型不得排斥 Multiclass),但不用現在決定 P2 Token table 或 P5 Tactical renderer。後續 Phase 開工時以當時真正存在的 codebase 為基礎再設計,比現在猜測可靠。
  2. 所有正常產品 Phase 在 coding 開始前,都必須先拆成 P<n>-AP<n>-B… 的 Subphases。所有 Maintenance / Modification Phase 在 coding 開始前,都必須先拆成 M<nn>-AM<nn>-B… 的 Subphases。 每個 Subphase 必須能獨立實作、驗證並 commit;完成時應處於可執行、可測試、沒有已知編譯/型別/該 Subphase 測試錯誤的狀態。
  3. M Phase 定位M01M02… 用於補資料/補設定、既有能力加強、資料 migration、或不構成下一個正常產品里程碑的維護/修改工作。M Phase 可以插在 P Phase 之間,也可以插在另一個 M Phase 的兩個 Subphase 之間;但不改寫 P0 → P1 → P2... 的正常 Roadmap。Maintenance / content 型 M Phase 也可以長期保持 open,讓正常 P Roadmap 繼續前進;除非 PROJECT_BRIEF.md 或該 Phase 契約明確指定 dependency,整個 M Phase 的「final closeout」不是進下一個 P Phase 的必要條件。 每個已拍板的 M Subphase仍各自 closeout,後續新增時照下一個字母接續,不重編已完成項目。
  4. U Phase 定位U01U02… 用於 Test / Development Efficiency Optimization,例如測試速度、開發迴圈成本、CI 效率與相關可靠性。U 類不改寫產品 P0 → P1 → ... Roadmap,也不是內容 Maintenance;可以與 P / M 工作並行,整體長期保持 open、不設 Full Closeout。每個具體項目仍使用 U<nn>-AU<nn>-B…,各自實作、驗證、commit 與 closeout。U 類每個 Subphase 使用單一文件 docs/Uxx/Uxx-<letter>.md,同檔承載實作規格、開發設計、測試與證據,不套 P / M 的三份文件制;優化不得犧牲 correctness、資料隔離或既有產品行為。
  5. Subphase 只拆當前 Phase。唯一例外:使用者已明確決定要插入、且插入點已確定的 M Phase,可以在插入點到達前先完成拆分與三份文件(M02 即為此例,插入點固定在 M01-C closeout 後)。此例外只適用已拍板的插入,不適用「將來可能會做」的 Phase。
  6. 同一 Phase 的 實作規格.md開發設計方針.md測試指南.md 必須使用完全一致的 Subphase 名稱與順序,讓實作者可用 Subphase id 精準取得三份契約;U 類依第 4 條使用單檔格式。
  7. PROJECT_BRIEF.md 在當前 Phase 已拆分後,必須一列一個 Subphase 顯示進度,不可再用「P0(含 A~F)」或「M01(含 A~K)」合併成一列;U 類同樣一列一個 Subphase。
  8. 長期 M Phase 的跨 Phase 相容性隨 Roadmap 前進而擴大。 當後續 P Phase 已存在時,新 M Subphase若修改共享 domain / persistence / schema / DTO,除了本 M Subphase自己的 regression,還要 review並驗證所有直接受影響、已完成的後續 P Phase;不能只用「這是舊 M Phase」為理由忽略新 consumer。

修改授權與驗證規則

除非使用者明確要求「修」、「修改」、「實作」、「處理某個 phase」、「commit」或「提交」,否則不得:

當使用者要求「驗證」,或只是描述錯誤、貼截圖、詢問原因、要求解釋、要求列出問題、詢問某功能怎麼使用時:只能進行檢查、讀檔、執行測試、code review、啟動本機服務與回報結果。若發現問題,只列出問題、影響範圍與建議修法,等待使用者下一步指示。

設計討論的方式

每個問題都要先想好一個解法再拿出來討論。 不要把開放題原封退回給使用者。

只有符合以下條件才回頭問使用者:A/B 選擇會明顯改變跑團方式、影響 DM / Player 核心權利、改變規則玩法、造成難以逆轉的產品方向,而且從既有規格無法合理推導。純技術或一般 UX 問題自己決定。

產品層實作守則

  1. Server 是唯一真實狀態來源。 AI 不直接操作 DB raw fields;Human 與 AI 使用同一套 GameAction / backend logic。
  2. 秘密靠 Server 過濾,不靠 UI 隱藏。 Secret DC、DM Notes、Hidden Monster、他人 private knowledge 不送給 Player / AI Player。
  3. Optional 不得變 Mandatory。 Quest、Scene、NPC、Position Note、Campaign Fact 等可以完全不建立而繼續跑團。
  4. 網站不接 LLM API。 後端沒有模型可呼叫,所有 AI 能力來自使用者的外部 AI Session。
  5. 內容逐步擴充,SRD 5.1 是起點不是上限。 非 SRD 內容依實際需要逐步加入。
  6. Human UI 與 AI MCP 共用同一份 backend logic,不做兩套遊戲邏輯。
  7. M03 已交付單機版,standalone boundary 從此是常駐約束。 新增任何 P Phase / M Phase 都不得違反 docs/M03/實作規格.md 3.2 的界線:app.standalone 不得 import app.mainapp.content.*app.domain.character* 與 protected module 不得觸及 Room / Campaign / Session / Seat / Party Roster 等多人層。P2 引入多人模組時,必須同步擴充 tests/test_m03_import_boundary.py 的 forbidden regex 與 EXACT_PROTECTED_MODULES,否則新命名會讓 gate 靜默放行。之後任何長期 M01 工作若修改 Character Build / State / Version / StableKey / Builder provenance / Character JSON,也必須重新檢查 standalone composition 與 Web↔Standalone exchange 相容性,不能讓角色核心反向依賴多人層。

工程實作守則

  1. API 簽名預先核對:呼叫任何專案內模組或 API 前,先 grep / 讀檔核對最新定義與參數列,不憑記憶編寫。
  2. 已授權改動引入的錯誤同 turn 修完:跑測試或檢查時取得完成結果;已獲修改授權時,本次改動引入的編譯、型別與測試錯誤必須在同一 turn修復並驗證。驗證模式或發現授權範圍外的既有問題時,只回報問題、影響與證據,不自行擴大修改範圍;若因環境或外部依賴無法完成驗證,明確回報阻礙,不宣稱通過。
  3. 驗收對應:每條 Phase / Subphase 驗收契約都要有可定位的測試證據。
  4. 測試分層 gate:測試範圍依改動範圍決定,不是每次都跑全部。
    • 純文件修改:未改變產品/實作/驗收契約時,只核對內容一致性、連結與 diff,不適用下列程式改動 gate,也不因合併回 main 而重跑全套 E2E。若文件修改涉及上述契約,須核對對應實作與證據,必要時執行受影響的驗證;若是在辦理 Subphase/Phase 關門,仍須確認該階段 gate 的證據完整,不能以純文件提交豁免,也不因整理既有有效證據而重跑測試。
    • 每次改動:該 Subphase 的 focused test,加上被改到那一側的單元測試(backend pytest tests/test_<subphase>_*.py,cwd 為 apps/server;frontend npm test -- --runnpm run build)。
    • Subphase 關門:全套 backend pytest、全套前端單元測試與 build、docker compose config,以及該 Subphase diff 觸及的畫面/流程對應的 E2E spec
    • Phase 關門與合併回 main:全套 E2E。
    • 判準:diff 只動 backend / DB / 打包相依而不碰 apps/web 者為 backend-only,Subphase 關門不需要跑 E2E;一旦動到 apps/web,或動到 server 送給前端的 DTO、machine code、locale 字串,就要跑對應的 E2E spec。
    • 各 Phase 若有專屬對照(哪個 Subphase 配哪組 E2E spec),寫在該 Phase 的 測試指南.md;沒有特殊情況者直接沿用本條,不需重述。
  5. 權限與可見性必測:當 Phase 涉及 Role / Seat / Controller 時,除了 happy path,必測不該看到/不該操作的 actor。
  6. 拒絕原子性與 fixture 隔離:契約要求零副作用的拒絕操作,前後狀態不可被污染;測試 fixture 必須完整還原。
  7. Supported locale 同步交付:新增、修改,或因新畫面而首次 expose user-visible system / rules content 時,必須在同一個 Subphase 同步補齊所有正式 supported locale(目前為 zh-TW / en),包含 UI copy、rules presentation field、validation / error 訊息與 searchable 欄位。缺任一語言視同該 Subphase regression,不得以「先做英文、之後再補 M Phase」結案。
  8. 發版相依不得漂移:Windows standalone 發版一律依 apps/server/constraints-standalone-win.txt 安裝,本機與 CI 共用同一份清單。pyproject.toml 只宣告需要哪些套件與相容範圍,實際版本號只住清單,不抄進其他文件。新增 Python 套件、升級既有套件或更換發版 Python版本時,必須在同一個改動內重新產生清單、跑過 standalone build 與 frozen smoke 再提交。scripts/check_standalone_env.py 會在 build 期擋下與清單不符的環境;不得為了讓 build 通過而繞過、放寬或跳過它。操作步驟見 README.md

修改任務的完成條件

使用者明確要求修改文件、程式、資料、設定或實作功能時,授權包含完成必要驗證後的 commit 與 push。除非使用者明確要求暫不提交、暫不推送或先看 diff,否則必須在同一任務內完成,不需再次詢問。本條適用所有修改任務,包含已獲授權的文件關門,不限 implementer 或 verifier。


本機 Windows 環境專用

本段僅適用於使用者本機 Windows 環境(工具都在 C:\)。remote / CI / Linux session 沒有這些路徑與工具,跳過本段。

專案路徑:C:\_work\AI_Work\Projects\adventure-table

Python 執行環境規則

一律使用專案根目錄的 .\.venv\Scripts\python.exe,讓 agent 與使用者看到一致結果。

Backend server app 的指令(pytestalembicuvicorn)cwd 一律為 apps/server,直譯器一律 ..\..\.venv\Scripts\python.exe。兩行分開下,不要用 cd ... && ... 串成單行——本機是 Windows PowerShell 5.1,沒有 &&

cd apps/server
..\..\.venv\Scripts\python.exe -m pytest tests/test_<subphase>_*.py

tests/test_m03b_migration.py 等測試用裸相對路徑讀 alembic.inialembic/versions/,cwd 不在 apps/server 會失敗;pytest 的 rootdir 解析到 apps/server/pyproject.toml 不代表 cwd 也跟著換。

例外:scripts\ 底下的發版與 smoke 工具從 repo root 執行,並使用工程實作守則第 8 條指定的 .standalone-venv / STANDALONE_PYTHON,不是這裡的 .venv

E2E 測試執行規則

Windows 上不得讓 Playwright 託管 vite。 dev server 會在跑測試途中停止接受連線,造成數十個 net::ERR_CONNECTION_REFUSED(KI-ENV-001,上游 vite 未修)。整套 E2E 一律走容器裡的 Linux dev server:

cd apps/web && npm run test:e2e:docker

該 script 內的 --build 不可省——web service 沒有掛 bind mount,略過重建會靜默測到上一版 frontend。

playwright.config.ts 會直接擋下 Windows 託管路徑;要重現該 dev server問題才設 ALLOW_WINDOWS_VITE_E2E=1。細節見 已知問題.md 的 KI-ENV-001。

本機工具

外部工具不放進本專案 repo。

工具 路徑 用途
Codex DeepSeek home C:\_work\AI_Work\Tools\codex-deepseek-home DS reviewer 環境
Antigravity CLI C:\Users\User\AppData\Local\agy\bin\agy.exe agy reviewer

外部 Reviewer CLI

三個 reviewer 共通:預設 read-only——不寫檔、不刪檔、不 stage、不 commit、不 push,不讀 .envC:\_work\AI_Work\Tools\;非互動呼叫必須 < NUL 關閉 stdin,否則會停在等待輸入永久卡死;輸出重導到檔案保留;結果只當第二意見,回報前先自己審一遍,並以 git status / git diff 確認實際改動。

觸發語 走哪個
「要 ds4 / ds4 pro / ds4 flash 做 XXX」 DeepSeek via Codex CLI
「要 agy 做 XXX」「用 agy 審 / 驗證 XXX」 Antigravity CLI
「要 codex 做 XXX」(不帶 ds4 Codex CLI (OpenAI)

DeepSeek via Codex CLI:透過本機 Moon Bridge DeepSeek 設定,用 CODEX_HOME=C:\_work\AI_Work\Tools\codex-deepseek-home。Model:ds4 prodeepseek-v4-prods4 flashdeepseek-v4-flash;只說 ds4deepseek-v4-pro

Antigravity CLI:binary 在 user PATH,但部分 shell 的 PATH 快照可能沒有,直接用完整路徑最穩。

cmd /c "C:\Users\User\AppData\Local\agy\bin\agy.exe -p `\"<任務>`\" --model `\"<模型>`\" --add-dir `\"C:\_work\AI_Work\Projects\adventure-table`\" --dangerously-skip-permissions --print-timeout 540s < NUL > <輸出檔> 2>&1"

--add-dir 讓 reviewer 讀到專案,--dangerously-skip-permissions 單次生效不動持久設定,兩者都不可省。Model:--modelagy models 列出的完整顯示字串,未指定時預設 "Gemini 3.5 Flash (High)"

Codex CLI (OpenAI):用預設 CODEX_HOME

cmd /c "codex exec `\"<任務>`\" --sandbox read-only -C `\"C:\_work\AI_Work\Projects\adventure-table`\" --ephemeral -o `\"<結果檔>`\" < NUL > `\"<過程log檔>`\" 2>&1"

--sandbox read-only 是引擎層強制唯讀,寫入任務才改 --sandbox workspace-write-o <結果檔> 只寫最終回覆,與 stdout 的完整過程 log 分離。Model:預設依本機 Codex 設定,要換用 -m <model>,專注程度用 -c model_reasoning_effort="low/medium/high" 覆蓋。