生活分享
修 Bug 的完整流程
好的除錯从可重現的症狀開始,再用證據縮小原因,最後驗證修正。『網站壞了』不夠具體;提供哪個輸入、在哪個步驟、期待什麼、實際出現什麼,能讓 Codex 更快找到相關程式。
閱讀時間約 14 分鐘 · 操作 25 分鐘

返回 Codex 教學總目錄Codex 學習中心:完整教學目錄從安裝、第一個任務到 MD 規則與進階整合,規劃 60 篇 Codex 教學、十個單元。依程度、平台、需求或指令搜尋下一篇;尚未公開的教學會標示狀態,方便安排學習路線。閱讀全文
目標與準備
本段提到的教學與資源: 既有專案閱讀先讀懂一個既有專案用唯讀流程找到啟動點、資料流與測試,產生有檔案依據的專案地圖。閱讀全文
步驟 1:固定故障版本與重現步驟
從練習 ZIP 的 broken 複製五個檔案到新資料夾 codex-bug-lab,保留原版。這份程式已有篩選分支,但 Completed 的條件故意寫反;與 start「尚未實作篩選」不同。開編輯器,PowerShell 用 Get-Location、macOS/Linux 用 pwd 確認位置,再執行既有測試,預期 2 過 1 敗。
node --test core.test.mjs
要確認畫面,從本目錄啟動本機預覽:Windows 執行 py -m http.server 4173 --bind 127.0.0.1,macOS/Linux 執行 python3 -m http.server 4173 --bind 127.0.0.1。開 http://127.0.0.1:4173;若有想保留的虛構資料先記錄,再使用 Reset practice data,切到 All tasks 並確認空清單。接著依序新增 Read、Build,只勾選 Read,再切 Completed。預期應是 Read,故障版實際卻顯示 Build;把這個順序完整記下。資料重設不會還原程式檔。
故障報告要帶執行環境、起點、操作、預期、實際與證據,先不要填「原因一定是快取」。下列範本只記已觀察的現象;日期與測試結果由你填入。若你的畫面顯示不同,先核對預覽目錄及是否混入 expected,不把文章預期硬寫成自己的實測。
# Bug: Completed shows unfinished tasks
Environment/date: fill from this run
Fixture: broken copied to codex-bug-lab
Steps: reset practice data; add Read and Build; complete Read; select Completed.
Expected: Read only.
Observed: Build only, if reproduced.
Baseline: node --test core.test.mjs; fill actual result.
Scope: keep UI, storage format, ordering and tests unchanged.
Root cause: not confirmed yet.
Unperformed checks: list explicitly.
步驟 2:建立不依賴畫面的最小重現
在根目錄新增 repro.mjs,貼入下面完整程式。它直接把一個已完成與一個未完成任務送給 visibleTasks,不經 localStorage、DOM、瀏覽器快取或外部網路。保存後在另一個終端機執行 node repro.mjs。故障版應先印出實際 b,再因期待 a 而以非零狀態結束;這次 assertion 失敗就是要保留的證據。
import assert from "node:assert/strict";
import { visibleTasks } from "./core.mjs";
const tasks = [
{ id: "a", title: "Read", completed: true },
{ id: "b", title: "Build", completed: false },
];
const actual = visibleTasks(tasks, "completed").map((task) => task.id);
console.log("Completed IDs:", JSON.stringify(actual));
assert.deepEqual(actual, ["a"]);
console.log("Reproduction passed.");
node repro.mjs
現在可以縮小調查:核心函式在沒有瀏覽器的情況下就已回傳錯誤,故障不需要快取或按鈕事件才能發生。這不能證明所有 UI 都正確,但足以先查核心 Completed 分支。請 Codex 用證據解釋「為什麼目前條件選中了未完成任務」,再談修正;不要以一次重新整理偶然正常當根因已找到。
先分辨程式失敗與環境失敗
若 node repro.mjs 顯示 ERR_MODULE_NOT_FOUND,尚未執行到 Completed 斷言,先檢查目前資料夾與 core.mjs 的檔名;若是 SyntaxError,核對是否完整貼上程式。只有程式成功載入,印出 b,接著因期待 a 而失敗,才是此缺陷的重現。反過來,第一輪直接通過也不是你已修好:可能拿到 expected 副本,應回查材料來源。把命令、退出碼、實際輸出及副本位置一起留下,不只記「紅色」或「失敗」。
步驟 3:要求最小修正與原因說明
桌面版先以 codex-bug-lab 建立 Codex 任務;CLI 則在該資料夾確認路徑後執行 codex。接著送出下面的完整要求,將範圍限定到 core.mjs 的 Completed 條件。既有測試與 repro.mjs 都不要修改,否則無法比較前後。教材的故障註解在修好後會過期,可一併移除那一行;除此以外不重構所有函式、不改 UI 文案、不換框架。若代理沒有讀測試輸出,就要求先確認原始失敗再繼續。
Fix the reproduced Completed-filter bug in this codex-bug-lab.
First read core.mjs, core.test.mjs and repro.mjs. Run node repro.mjs and node --test core.test.mjs to confirm the current failure.
Explain the predicate error using the actual a/b IDs. Modify only the completed predicate in core.mjs and remove its obsolete deliberate-bug comment. Do not change tests, repro.mjs, active behavior, storage or UI.
Rerun both commands, inspect the final diff and report actual results. Browser checks must be marked NOT RUN unless actually performed. Do not publish or deploy.
根因是 Completed 使用 !task.completed,與 Active 一樣選未完成;正確條件是 task.completed。只需把該分支改成下列一行,不要連 Active 的 ! 也刪除。若只把下拉選單的標籤交換,畫面有時看起來合理,但 repro 仍會失敗;這說明修表象與修行為是兩件事。
if (filter === "completed") return tasks.filter((task) => task.completed);
步驟 4:用同一證據做回歸
修正後 node repro.mjs 應印出 ["a"] 與 Reproduction passed,退出碼為 0;原測試應 3 項全過。再依第一步相同操作重測畫面:Completed 只有 Read,Active 只有 Build,All 保留兩筆。先用相同輸入證明原錯誤消失,再新增空清單與取消完成等邊界,不要一開始換整批資料而失去前後比較。
| 證據 | 修正前 | 修正後 |
|---|---|---|
| 最小重現 | b,assertion 失敗 | a,退出碼 0 |
| 原本核心測試 | 2 過 1 敗 | 3 過 0 敗 |
| Completed 畫面 | Build | Read |
| Active/All | 需記實際結果 | Build/兩筆皆在 |
| 尚未做的檢查 | 明列未執行 | 不自動改成通過 |
最後看 core.mjs 的差異,確認沒有改 addTask、decodeTasks 或測試期待。若對方回報修好了卻沒顯示執行結果,要求命令、退出狀態及失敗摘要;不能執行時就記原因。兩個測試通過也不能取代真正畫面檢查,要由你或具備瀏覽器工具的代理完成,並標明平台與預覽網址。
補驗取消完成與空清單
原重現已通過後,另建 regression.mjs,貼上下面程式,再執行 node regression.mjs。它先驗證 Completed 的 a,取消 a 的完成狀態後驗證 Completed 為空、Active 保留 a/b,並檢查原輸入未被改動與三種空清單。預期印出 Regression passed,退出碼 0。它是獨立斷言程式,不會把原 node --test core.test.mjs 的測試數自動增加。
import assert from "node:assert/strict";
import { toggleTask, visibleTasks } from "./core.mjs";
const tasks = Object.freeze([
Object.freeze({ id: "a", title: "Read", completed: true }),
Object.freeze({ id: "b", title: "Build", completed: false }),
]);
const ids = (items, filter) => visibleTasks(items, filter).map((task) => task.id);
assert.deepEqual(ids(tasks, "completed"), ["a"]);
const changed = toggleTask(tasks, "a");
assert.deepEqual(ids(changed, "completed"), []);
assert.deepEqual(ids(changed, "active"), ["a", "b"]);
assert.deepEqual(ids(changed, "all"), ["a", "b"]);
assert.deepEqual(tasks.map((task) => task.completed), [true, false]);
for (const filter of ["all", "active", "completed"]) {
assert.deepEqual(ids(Object.freeze([]), filter), []);
}
console.log("Regression passed.");
node regression.mjs
原 broken/core.mjs 還原練習也保留 regression.mjs;它應再次以非零狀態失敗,與 repro.mjs 的 b 一致。若你另外更動測試、標籤或保存流程才讓結果轉綠,回到保存的原檔重新做單一修正,並在交接紀錄上下文與工作交接長工作需要把決策與證據留下,不能只依靠對話長度。README 說明怎麼使用專案,設計文件記錄為何這樣做,交接文件整理目前做到哪裡;AGENTS.md 則放持續有效的工作規則,避免把所有進度塞成規則。閱讀全文標示這次被捨棄的假設。完整回歸仍需實際畫面與重載檢查,未做就保留未執行。
排錯習慣、還原與交付
一次只改一個可驗證的假設,失敗時把「做了什麼、得到什麼」追加到報告,避免下一個任務再次重試相同無效修正。若根因不在本篇預設位置,保留新證據並重新縮小範圍,不因為教學說一行就硬改一行。真實專案的計時、帳號及網路條件可能造成不同故障,重現資料應先去除私人內容再交給 Codex。
交付包含 Bug 報告、最小重現、原因、限定差異及回歸表。要重做時,停止自己的預覽,只把原 broken/core.mjs 複製回來,保留 repro.mjs;它應再次失敗,原測試回到 2 過 1 敗。需要完整功能案例時接功能驗收篇實作功能:完成待辦篩選從 start 材料補上 Active/Completed 篩選,保留資料格式並用正常與邊界案例驗收。閱讀全文。圖中 1 是重現,2 是定位修正,3 是回歸;參考修正可本機驗證,Codex 實際對話和各平台操作仍要依你的執行記錄判定。
返回 Codex 教學總目錄Codex 學習中心:完整教學目錄從安裝、第一個任務到 MD 規則與進階整合,規劃 60 篇 Codex 教學、十個單元。依程度、平台、需求或指令搜尋下一篇;尚未公開的教學會標示狀態,方便安排學習路線。閱讀全文
閱讀完整文字說明
Reproduce to Fix to Regression
同主題延伸閱讀
生活分享
Codex 學習中心:完整教學目錄
從安裝、第一個任務到 MD 規則與進階整合,規劃 60 篇 Codex 教學、十個單元。依程度、平台、需求或指令搜尋下一篇;尚未公開的教學會標示狀態,方便安排學習路線。
生活分享
Worktree 與多任務隔離
Worktree 讓同一個 Git 程式庫有不同的工作目錄,各自承接不同分支。它適合讓兩項工作分開改檔,但資料庫、連接埠與外部服務仍可能共用,不能把檔案隔離當成所有資源隔離。
生活分享
實戰:製作小網站
從 brief.md 規劃並製作 Small Steps 待辦網站,完成新增、完成、刪除、篩選與本機資料保存。將 HTML、CSS、資料函式、畫面事件與測試分開,以 Node 測試和瀏覽器操作驗收,並留下可重新啟動與還原的交接紀錄。
生活分享
用量與效率:減少重工
記錄任務條件、模型選項、時間與成果,找出能減少無效重試和過多上下文的調整。
引用本文的文章
最新旅遊情報攻略

情報
2026 韓國楓葉預測:雪嶽山 10 月 20 日、首爾近郊 10 月底、內藏山與漢拏山 11 月上旬
韓國山林廳 2026 年 9 月 22 日公布的楓紅高峰預測:雪嶽山 10 月 20 日,春川、國立樹木園到首爾植物園落在 10 月 28 日到 11 月 2 日,內藏山 11 月 4 日、漢拏山 11 月 6 日,整體比最近 5 年晚約 0.8 天。整理各地楓樹與銀杏的預測日、首爾出發怎麼排,以及出發前去哪裡看即時楓況。2026 年 10 月查證。
- 季節活動
- 自然
- 觀景

攻略胡志明市
胡志明市到頭頓一日遊:白藤碼頭搭高速船、船票與班次,下船就是胡梅纜車與耶穌基督像
人在胡志明市挪一天去頭頓看海:市中心的白藤高速船碼頭搭船,航程 120 分鐘到頭頓的胡梅碼頭,平日成人 320,000 越南盾、週末 350,000,回程末班平日 15:00。下船就是胡梅纜車站,同一條路上有白宮,小山頂上是耶穌基督像。平日一天只有兩班船,整天要從末班船倒推著排。
- 交通
- 行程範例
- 海灘

攻略沖繩
沖繩不開車攻略:單軌只到浦添,美麗海水族館要坐兩個多小時的巴士,回那霸的最後一班直達車 17:22 就開走
不租車的沖繩怎麼移動:那霸市區靠沖繩都市單軌電車(ゆいレール),那霸機場站到終點てだこ浦西 19 站、17 公里、37 分鐘,一日券 1,000 日圓;美麗海水族館有那霸機場直達的高速巴士,單程 2,000 日圓起、官方時刻表上 2 小時上下,下車後還要走 10 分鐘;古宇利島要在今帰仁村役場轉車,當天來回光坐車就六個半小時;回程的最後一班直達車 17:22 就從記念公園前開走(2026 年 9 月查證)。
- 交通
- 行程範例
- 預算