fix(starpuff): 生產站 commit 指紋根修+存檔寫入失敗提示(#868)+v14 驗證腳本 SSOT(#872) - #877
Merged
Conversation
- .dockerignore 排除 .git 且 Zeabur 不提供 GIT_COMMIT_HASH,starpuff production 恆落純 v0.22.1,同版號兩次部署無鑑別力,發版無法驗證實際上線 commit - 查證 Zeabur 官方文件:建置階段內建特殊變數 ZEABUR_GIT_COMMIT_SHA https://zeabur.com/docs/en-US/deploy/config/environment-variables - Dockerfile builder 段宣告 ARG/ENV 使 Zeabur 自動注入(multi-stage 需求), 並修掉 export VAR="$(cmd)" 遮蔽 exit status 造成的靜默留空,改印 build fingerprint 供部署 log 取證 - 來源鏈收斂為 scripts/lib/build-commit-sha.mjs 跨 app SSOT: ZEABUR_GIT_COMMIT_SHA → GIT_COMMIT_HASH → git rev-parse → 省略後綴 - GAME_DESIGN §99 補取代標註;002 記錄根因與解法 測試:pnpm typecheck 全綠;新增 build-commit-sha 8 案單測並掛入 test:root; 實跑 docker build 驗證 build log 指紋與映像內嵌 v0.22.1+9505d2b Co-authored-by: Cursor <cursoragent@cursor.com>
- persistSave 回傳主檔寫入結果;備援輪替失敗不影響判準(主檔寫得進去即成功) - GameScene 通關落盤消費失敗訊號,觸發與開機提示同一張「進度無法保存」殼卡 - 提示文案收斂為 shellCards.notifySaveUnavailable 單點,每工作階段至多一張, 仍走 whenShellIdle——遊戲進行中延後到 Title 安靜時刻,不攔截操作 - isSaveStorageAvailable 探測負載改對齊實際主檔體積,1 字元 probe 不再誤判可寫 測試:save.test 補 5 案(回傳值、QuotaExceededError、備援失敗不影響、配額邊界探測、 無存檔退回 1 字元)、shellCards.test 補提示路徑與單次守衛;starpuff 全量 938 案綠 Co-authored-by: Cursor <cursoragent@cursor.com>
- T7-A migration 落盤成功即刪 sp-muted/sp-rotation/sp-key-layout,腳本以 legacy 鍵判定會恆為 FAIL 並誤導後續驗收 - 新增 scripts/lib/settings-fixture.mjs 作腳本側偏好 SSOT(key 與 schemaVersion 對齊 core/settings.ts),六支 v14 腳本改讀寫 sp-settings - v14-g 判定前提一併修正:震動已與靜音解耦,閘門為 hapticsEnabled 而非 audioMuted - 專測 migration 的腳本(v16-legacy-qa/v16-d1、v14-e 場景一輸入)刻意保留 legacy 鍵並加註說明 測試:實跑 v14-c(四組 insets 全 PASS,含 mute 命中與 cw 持向前置)與 v14-g (PASS 關閉觸覺不震);v14-notice PASS;v14-b 結果與 base 基準一致(既有 cw 搖桿 FAIL 非本次引入);v14-e/v14-f 受既有 data-menu="config" 入口改版阻擋, 未能實跑,靜態收斂並另報 Co-authored-by: Cursor <cursoragent@cursor.com>
Contributor
Dependency Review✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.Scanned FilesNone |
Contributor
|
✅ SEO 審計通過!所有 2026 標準驗證項目都符合要求。
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 816438331a
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| const probeKey = 'sp-storage-probe'; | ||
| localStorage.setItem(probeKey, '1'); | ||
| localStorage.removeItem(probeKey); | ||
| localStorage.setItem(STORAGE_PROBE_KEY, probePayload()); |
Comment on lines
+96
to
+97
| localStorage.setItem(key, value); | ||
| document.documentElement.classList.add('sp-rot-cw'); |
There was a problem hiding this comment.
Contributor
Author
- main.ts 開機成就補發落盤失敗改觸發 notifySaveUnavailable,不再丟棄回傳值 - save.ts 備援自癒回寫明文標為唯一例外並寫出理由:備援仍完好、下次開機會重走 同一恢復路徑、loadSave 為 boot/Title/Map 多處熱呼叫於此提示會洗版 - persistSave 模組註解同步指向該例外,契約不留模糊地帶 測試:pnpm --filter @app/starpuff test:run Co-authored-by: Cursor <cursoragent@cursor.com>
- 腳本 fixture 常數為手抄值(node 腳本無法 import TS),與 core/settings.ts 分家 且無守門,schema bump 漏同步會讓 fixture 被判版本不符整段回退預設 - settings.test 補兩案:常數逐一相等、fixture 產物實際餵 parseSettings 須被接受 - 補 settings-fixture.d.mts 型別宣告供 TS 側消費 測試:刻意 bump fixture 版本驗證守門紅(2 案 fail)再還原綠;settings.test 15 案綠 Co-authored-by: Cursor <cursoragent@cursor.com>
- 既有測試 stub 讓 Title 恆在,等於繞過該規則,新增提示呼叫點時無回歸保護 - 補兩案分別鎖住兩個忙碌訊號:非 Title、controls is-active——advanceTimers 後 overlay 必須為 0,解除忙碌後才變 1 - 補 dev-only __resetSaveUnavailableForTests 消除模組級單次守衛的跨案污染 測試:拔掉 whenShellIdle 忙碌守衛驗證 3 案轉紅再還原綠;shellCards.test 5 案綠 Co-authored-by: Cursor <cursoragent@cursor.com>
- SHA_PATTERN 實際擋得住髒值,但既有 8 案未鎖這條路徑,放寬 pattern 不會被抓到 - 補 2 案:zzzzzzz/9505d2b!e/refs/heads/main 皆不算命中續往下一來源; git 退路自身回傳錯誤訊息時亦不採信 測試:npx vitest run scripts/__tests__/build-commit-sha.test.ts → 10 案綠 Co-authored-by: Cursor <cursoragent@cursor.com>
- probePayload 下限改為預設存檔含 checksum 的實際落盤體積,無存檔時不再退回 1 字元 - 對應單測雙向鎖定:配額容不下即回報不可用、容得下則不誤報 - Dockerfile 於 shell 側以 hex 樣式校驗後才 export 建置雜湊,髒值一律清空 - 002 記分行更新為 +8(reward 8、penalty 0、neutral 0)|累計總分 +250 測試:pnpm typecheck(9/9 專案)、starpuff vitest 943 案全綠、pnpm lint 0 錯誤 Co-authored-by: Cursor <cursoragent@cursor.com>
Contributor
|
✅ SEO 審計通過!所有 2026 標準驗證項目都符合要求。
|
- 002 修正 regex 語意過聲稱:標明 shell 與 JS 字面 class 相同但不完全等價 - 002 改稱測試用匯出:__resetSaveUnavailableForTests 執行期無 env 閘僅命名慣例 - save.ts 例外註解刪去「反覆洗版」誇大句,改述下次真實寫入會觸發同一張卡 - 補 1 案貫穿測試:主檔損毀+備援合法+回寫拋錯,鎖備援逐字不變與恢復後落盤 測試:typecheck 全通過;starpuff 944 案全綠(68 檔);lint 0 error;prettier 全通過; 新測試以兩種 loadSave 變異驗證紅→綠 Co-authored-by: Cursor <cursoragent@cursor.com>
Contributor
|
✅ SEO 審計通過!所有 2026 標準驗證項目都符合要求。
|
s123104
pushed a commit
that referenced
this pull request
Jul 26, 2026
- 併入 main 對 §99 的 SHA 來源鏈修正(#877),依主句紀律改寫並移入 00-foundations - 002 條目雙方時間序全保留零刪除;檔頭重算為 reward 9/neutral 2、淨 +9、累計 +260 測試:002 六項驗算全通過(條目數/前綴計數/N=a-b/T=main 251+9/ID 唯一/零刪除) Co-authored-by: Cursor <cursoragent@cursor.com>
s123104
added a commit
that referenced
this pull request
Jul 26, 2026
* chore(starpuff): T7-C 文件 SSOT 收斂開工活性錨 - 建立 docs/starpuff-t7c-split 分支與隔離 worktree - 後續處理 GAME_DESIGN.md 拆分與 issue #871 文件漂移 測試:無(空 commit 活性錨,不含程式碼變更) Co-authored-by: Cursor <cursoragent@cursor.com> * docs(starpuff): 修正 GAME_DESIGN 與 T7-A 實作漂移(#871) - §62 慈悲補血改確定性 pity 參數表:受傷/低血雙門檻+魔王 bossPityHurts=2,移除 35%/60% 擲骰 - 新增 §118 記載 sp-settings 單鍵 SSOT、統一設定頁、存檔備援 checksum 與 PWA 更新套用閘 - §9/§34/§35/§36/§38/§63.1/§70/§87/§89/§95/§101 舊敘述加註取代標記 - 三個 legacy 散鍵全檔不再作為現行規格敘述,僅保留為 migration 來源 - docs/dev/002 新增 reward 條目並更新記分行 測試:先讀 mercyHeal.ts/settings.ts/save.ts/pwaUpdateGate.ts 實作核對,prettier 3.8.1 格式通過;純文件變更未跑 vitest Co-authored-by: Cursor <cursoragent@cursor.com> * docs(starpuff): 依主題拆分設計 SPEC 並建立取代對照 SSOT(T7-C) - 2436 行單檔按 §NN 邊界機械拆為 design/00-08 九個主題檔,各檔開頭聲明職責範圍與邊界 - 新增 design/99-superseded.md:取代對照表(權威索引)+版本列車沿革+已失效內容搬遷區 - GAME_DESIGN.md 改為索引入口——章號對照表、主題檔一覽、硬不變式;路徑不變故外部引用不斷 - 章號 §N 不重新編號(src 註解直接引用),索引表負責章號到檔案的解析 - §15 v2 直向配置表、§43 v6 攻略表、§30 空中疾衝規格三塊全失效內容移入歷史檔並留指路句 測試:逐章比對驗證 118 章零遺失(115 章逐字元相同、3 章為刻意搬遷且規格行全數落在歷史檔), prettier 3.8.1 通過,全 repo grep 確認零錨點引用 Co-authored-by: Cursor <cursoragent@cursor.com> * docs(starpuff): 收斂攻略與 README 的實作漂移並開列大缺口 issue(T7-C) - WALKTHROUGH 慈悲補血改述保底計數(非抽獎),補設定頁段落與 v21–v23 落後聲明 - README 修正變身觸發面(SP 鍵非長按)、補星暴 2.0、EX 五王 P4、設定頁與成就系統 - 大缺口不擅改:#874 魔王主題招式需真機實測、#875 六模組註解誤引 §5、#876 PRD 漂移待裁決 - 002 檔頭記分行改為本 PR 聚合淨變化(squash merge 對齊) 測試:以 mercyHeal.ts/transform.ts/settingsPage.ts/achievements.ts 核對每項敘述, prettier 3.8.1 通過;攻略打法未重測故不新增打法敘述,改以聲明標示落後範圍 Co-authored-by: Cursor <cursoragent@cursor.com> * docs(starpuff): 補建 T7-C 文件修正 changeset(patch) - 依 AGT-VER-01 與 docs-only patch 先例補建 changeset,描述玩家可見的說明錯誤修正 - 002 新增 neutral 條目並更新記分行計數(reward 3、neutral 1,本 PR 淨 +3) 測試:prettier 3.8.1 通過;純文件與 changeset 變更,無行為影響故未跑 vitest Co-authored-by: Cursor <cursoragent@cursor.com> * docs(starpuff): 反轉取代標註方向——主句一律為現行規則(審查必修 1/2) - 全 10 個設計檔主句改寫為現行有效規則,舊規則降級為 35 條「已廢止」附註 - 99-superseded 新增「主句紀律」章立為鐵律,索引同步聲明,附註格式固定可 grep - 01 檔頭收窄職責為「輸入+與輸入直接連動的彈匣/蓄能狀態機」並說明為何不拆 §109.3 - 02 檔頭加星暴指路(現行規格在 §109.3),§63.1 歷史表 60% 去粗體並標 v9 限定 - 99 補回 §43 原引導句;002 新增 reward 條目 測試:prettier 3.8.1 通過;grep 抽驗 854×480/HP 70/168±14/35%/60% 等舊值全數 仍保留於附註內未遺失;純文件變更未跑 vitest Co-authored-by: Cursor <cursoragent@cursor.com> * test(starpuff): 新增設計文件索引守門並掛進 vitest(審查必修 3) - 新增 scripts/verify-design-docs.mjs:索引存在性/檔名/零重複/零缺號/標題同步、 每檔職責聲明、主句紀律附註格式、全 repo 零錨點引用共六類檢查 - 同名 .test.mjs 掛進 vitest(include 增 scripts/**/*.test.mjs),另設 pnpm verify:docs - 守門上線即抓到我漏更的 §60/§65 索引標題,已同步修正 測試:pnpm --filter @app/starpuff test:run 69 檔 936 案全綠(新增 4 案); 四種故障注入實證守門非空轉(漏登新章/索引指錯檔/重複章號/行內取代標註回歸)皆 exit 1 Co-authored-by: Cursor <cursoragent@cursor.com> * fix(starpuff): 設計文件守門排除自身避免檢舉自己 - 掃描器內含 GAME_DESIGN 錨點偵測字面值,入版控後被自己掃出三筆偽陽性 - 自身路徑改由 import.meta.url 推導後排除(非硬編,搬移改名仍成立) 測試:pnpm --filter @app/starpuff test:run 69 檔 936 案全綠; 另注入他檔錨點驗證自我排除未削弱偵測(07-art-audio-fx.md 仍被抓出) Co-authored-by: Cursor <cursoragent@cursor.com> * docs(starpuff): 補記守門自我排除 002 條目並重算 PR 聚合記分 - 新增 neutral 條目記錄 verify-design-docs 自我檢舉偽陽性的成因與修法 - 檔頭記分行重算:本 PR 共 7 條(reward 5、penalty 0、neutral 2),淨 +5、累計 +247 測試:prettier 3.8.1 通過;純文件變更未跑 vitest Co-authored-by: Cursor <cursoragent@cursor.com> * docs(starpuff): 修正 §60 L8 hint 主句與實作衝突(複審必修 HIGH) - 主句改為與 levels.ts:613 逐字一致的「站在地面按 SP 鍵星化變身」並加綁定標記 - 舊文案「地面長按吸入鍵 0.6 秒」降級為已廢止附註 - 該句原本無取代標註,故首輪 sweep 與守門的行內標註規則皆掃不到 測試:verify-design-docs 通過;逐字比對 levels.ts hint 與文件引述一致;prettier 通過 Co-authored-by: Cursor <cursoragent@cursor.com> * docs(starpuff): 收乾 02 檔頭自相矛盾與四節節點宣告(複審必修 MEDIUM 1/3) - 02 檔頭不再宣稱 §23/§40 星暴敘述皆為歷史值——§23 主句已是現行的自動結晶+SP - §50/§60/§65/§76 正文的「七/九/十二/十六節點單頁鋸齒」改為中性的新增節點敘述 - 舊佈局降級為已廢止附註(現行五區分頁見 §78);§50/§76 補齊引導句與 §60/§65 同構 測試:verify-design-docs 通過;rg 確認正文零殘留節點總數宣告;prettier 通過 Co-authored-by: Cursor <cursoragent@cursor.com> * test(starpuff): 守門補「已被」樣態並新增 doc↔code 引述綁定檢查(複審必修 MEDIUM 2+建議) - INLINE_SUPERSESSION 補被動語態「已被」,負向測試改參數化鎖三式(已由/已於/已被) - 新增引述綁定:文件標註「引述」(`來源檔.ts` 說明)後守門逐字比對 src,抄舊值即失敗 - 新增 hint 近似網攔截無標註的過期抄寫(Dice bigram,門檻 0.5 依實測校準並以單測鎖住) - 四處既有程式碼字串引述(L8 hint、變身首教浮字、結晶/帶星 toast)全數補上綁定標記 測試:verify-design-docs 通過;三種故障注入皆 exit 1(綁定抄舊值/無標記過期抄寫/ 綁定指向不存在來源檔);vitest 該檔 5 案全綠 Co-authored-by: Cursor <cursoragent@cursor.com> * docs(starpuff): 修正守門校準註解數字與 §76 附註漏帶推導值(終輪殘留) - 校準註解改實測值:全量 218 筆引述、近似網實際受檢 200 筆,並註明綁定後受檢集最高 0.182 - §76 已廢止附註補回「854 寬間距 ≈51px 單頁可容納」與「20 節點單頁確定放不下」 - 門檻 0.5 與 0.558/0.412 兩側校準值不變,仍由單測鎖住 測試:verify-design-docs 通過;守門單測 5 案綠;數值 token 逐檔比對全 10 檔零規格值遺失 Co-authored-by: Cursor <cursoragent@cursor.com> * docs(starpuff): rebase 至 main 並重算 002 總分鏈 - 併入 main 對 §99 的 SHA 來源鏈修正(#877),依主句紀律改寫並移入 00-foundations - 002 條目雙方時間序全保留零刪除;檔頭重算為 reward 9/neutral 2、淨 +9、累計 +260 測試:002 六項驗算全通過(條目數/前綴計數/N=a-b/T=main 251+9/ID 唯一/零刪除) Co-authored-by: Cursor <cursoragent@cursor.com> --------- Co-authored-by: haotool <haotool.org@gmail.com> Co-authored-by: Cursor <cursoragent@cursor.com>
This was referenced Jul 26, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
摘要
三項修復,各自獨立 commit:
v0.22.1,同版號兩次部署無鑑別力。sp-muted,靜音判定恆為 FAIL。1. 生產站 commit 指紋根修(
57c39118c)根因鏈(三段,缺一不可)
.dockerignore排除.git.dockerignoreL15.gitGIT_COMMIT_HASH,Dockerfile 的 git 退路又被export VAR="$(cmd)"遮蔽 exit status,靜默留空resolveAppVersion()兩個來源皆空 → 回退v${pkg.version}apps/starpuff/vite.config.tsL14-22(修前)Zeabur 環境變數查證
官方文件確認建置階段內建 Git 特殊變數(未憑記憶猜測):
${ZEABUR_GIT_COMMIT_SHA}:本次部署所屬的 Git commit SHA,僅於 build 階段存在ARG,Zeabur 才會於建置前自動注入修法
Dockerfilebuilder 段新增ARG ZEABUR_GIT_COMMIT_SHA+ENV;建置 RUN 依序GIT_COMMIT_HASH→ZEABUR_GIT_COMMIT_SHA→git rev-parse,並修掉 exit status 遮蔽($(cmd 2>/dev/null || true)+ 分離 export),另印build fingerprint:供部署 log 取證。scripts/lib/build-commit-sha.mjs(避免各 app 各寫一份):ZEABUR_GIT_COMMIT_SHA→GIT_COMMIT_HASH→git rev-parse→ 省略後綴(純vX.Y.Z)。含無效值防禦:空字串、未展開
${}佔位、不足 7 碼一律不採信;大寫正規化為小寫。zbpack.json明示build_type: dockerfile/dockerfile: Dockerfile,生效來源可確認。驗證證據
實跑正式 Dockerfile(僅給
--build-arg ZEABUR_GIT_COMMIT_SHA=9505d2b1e...,容器內無.git):映像內嵌版本字串:
另隔離驗證 Dockerfile shell 語意兩案:注入 Zeabur 變數 → 指紋成立;三來源全缺 → 不中斷建置(exit 0,印
<unavailable>)。其他 app 同缺口盤點
GIT_COMMIT_COUNT/git → pkgapp-version=2.27.2為純 pkg 版號)處理決策:Dockerfile 這一處修法讓
GIT_COMMIT_HASH對所有 app 的建置都真正可得(共用供給面 SSOT),且解析鏈已抽為共用模組供任何 app 一行接入。但未改動 ratewise / park-keeper 的 production 版本語意 — 它們的版號受verify-version-ssot與 changesets 治理,改動會牽動app-versionmeta、SEO SSOT 與發版驗證流程,屬高風險且超出本次缺陷範圍。建議 PM 另開卡裁決是否讓 ratewise 也帶 SHA 指紋。2. #868 存檔寫入失敗改為明確提示(
081594658)persistSave改回傳主檔寫入結果(備援輪替失敗不影響判準)。GameScene.persistAndAward通關落盤消費失敗訊號 →notifySaveUnavailable()。shellCards.notifySaveUnavailable單點(與開機探測提示共用),每工作階段至多一張,仍走whenShellIdle— 遊戲進行中延後到 Title 安靜時刻,不違反「杜絕戰鬥中彈窗」硬規則。isSaveStorageAvailable探測負載改對齊實際主檔體積(尚無存檔時退回 1 字元,不誤報)。測試:
save.test.ts+5 案(回傳值、QuotaExceededError回 false、備援失敗不影響回傳值、配額僅容 1 字元時探測回 false、無存檔退回 1 字元不誤報);shellCards.test.ts+1 案(顯卡路徑 + 單次守衛)。皆先紅後綠。3. #872 v14 驗證腳本改讀 UserSettings SSOT(
816438331)apps/starpuff/scripts/lib/settings-fixture.mjs作腳本側偏好 SSOT(key 與schemaVersion對齊core/settings.ts)。sp-settings:v14-c(mute 判定 + cw 前置)、v14-g(前置狀態)、v14-b/v14-f(cw 前置)、v14-e/v14-notice(判定依據)。v14-g判定前提一併修正:T7-A 已將震動與靜音解耦(audio/haptics.ts註解明示),閘門是hapticsEnabled而非audioMuted;只換 key 仍會 FAIL。v16-legacy-qa、v16-d1、v14-e場景一輸入)刻意保留 legacy 鍵並加註說明。實跑證據
v14-notice亦 PASS(pref=cw正確自sp-settings讀出)。已知限制 / 待 PM 裁決
v14-e/v14-f未能實跑:兩支腳本卡在[data-menu="config"]逾時。查證後確認是既有結構性漂移,與本 issue 無關 — T7-A 已把「按鈕配置」併入設定頁(openSettingsPage()),Title 次選單現為map/codex/skills/settings(桌機另有keys=操作說明,非按鍵配置)。本 PR 只做 legacy 鍵靜態收斂,未擴大範圍修入口路徑,建議另開卡。v14-bcw 搖桿 FAIL 為既有缺陷:已用 base9505d2b1e版本的原腳本實跑對照,兩側同敗(swipe-down => dx = -36vs 修改後-3,判定同樣 FAIL),非本次引入。驗證總覽
pnpm typecheckpnpm test(workspace + root)pnpm lintprettier --check未自行合併,等 PM 裁決。
Made with Cursor