如果只是一個邊界很清楚的 bug,普通 Turn 多半就夠了。但像 auth migration 這種工作,前面要先盤舊 client 被哪些地方依賴,接著一段一段換,每換一段又要跑 contract tests,最後還得確認 legacy path 真的清乾淨。每做完一小段就停回來等一句「繼續」,人很快就會變成那個一直幫它按下一步的人。

如果這幾個小時都還是在做同一件事,就可以交給 Goal Mode 接著跑。只要 outcome 和 success criteria 沒變,Codex 可以跨好幾個 Turn 繼續往同一個終點做,不需要每收掉一小段就停下來等下一句。[1][2][4]

如果六小時都在處理同一個 migration slice,那一個 Goal 仍然說得通;但兩小時裡混著 auth、首頁、文件和資料庫修改,反而很容易越跑越散。到底是六小時還是兩小時沒那麼重要,做到一半才發現原本那個 finish line 根本收不住這份工作,才麻煩。

A Goal Needs a Work Contract

Figure 1|Goal 需要一份 work contract。

Done when

OpenAI 給 substantial task 的 prompting guide 會把工作拆成 Goal、Context pointers、Constraints、Done when。[3] 這四塊寫在 task brief 裡,Goal Mode 介面不需要逐一對應四個欄位。一路需要保持不變的是 objective;背景資料、限制和驗收,放在 prompt、plan 或 spec 都可以。

拿同一個 auth migration 當示意,可以先寫成:

Goal
Migrate the target auth modules from the legacy client to the new auth client.

Context
Read the migration plan, current auth contracts, and tests under the target paths first.

Constraints
Keep public behaviour unchanged.
Do not redesign the session model.
Keep a rollback path until parity is verified.

Done when
Targeted tests and contract tests pass.
The target paths no longer reference the legacy client.
Pause and report if the old and new API semantics cannot be made equivalent without changing product behaviour.

如果 Done when 只寫 Refactor auth,Codex 幾乎隨時都可以說自己還在做。Contract tests 要過、target path 裡不能再留下 legacy reference,碰到 API semantics 無法等價時要停下來,這些才是它在每個 Turn 結束後能拿來判斷「還要不要繼續」的東西。Goal continuation 本來就會在 Turn 結束後檢查目標還有沒有未完成的工作;OpenAI collaborator 在官方 repo 討論 blocker 時,也建議把需要人介入的情況直接寫進 completion definition。[4]

Migration plan、介面 contract、edge cases 如果本來就有文件,用 Context pointers 指過去就好。[3] 只有 implementation 需要的細節留在 plan 或 spec;Goal 裡放幾個 Turn 之後仍然要成立的 objective。

Plan 收完,再讓它長跑

如果 migration 怎麼切、哪些 public behaviour 要保、session model 要不要一起動都還在談,這時先開 Goal 很容易留下後患。OpenAI 對大型任務的 guide 也是先 inspect context、整理做法,再進 implementation;官方 repo 裡談 Goal 時也有同樣的邊界,Plan 進行中會抑制 active Goal,planning 收完再設 Goal。[3][5]

小而清楚的 task 可以直接進 Goal,不用為了流程漂亮硬跑一次 Plan。麻煩的是架構還沒定,diff 已經先長出來。Codex 不會替你保留「這個方案目前只是討論中」的心理註記;目前指令允許它做,它就可能真的去做。

每天早上固定跑一次 issue triage,和一個下午都在跑的 auth migration,看起來都像「人不用每一步都下指令」,但控制的東西不一樣。前者要決定什麼時候把工作叫醒,後者要讓同一個 objective 從 inventory 一路留到 parity verification。之後可以放進同一個 workflow,平常選的時候先分開想,會清楚很多。

跑到一半怎麼看

Goal 跑起來後,不用每幾分鐘敲一次「好了嗎」。但幾小時後回來,如果只剩一串 transcript 和一句「還在處理 migration」,接手的人還是得自己考古。

Migration surface 盤完後,把 inventory 留著;target module 換完就看 focused tests 和 diff,準備清 legacy path 前再查一次還剩哪些 reference。別的 migration 可能切法完全不同,沒有固定 stage 也沒關係。回來時分得出哪一段做過、哪一段驗過,就已經夠了。

某一段 validation 爆掉,就先停在那一段處理。Goal 還在,不代表下一個 checkpoint 也要照跑。Status 不用寫長,現在做到哪裡、哪些東西已經驗過、還剩什麼、有沒有 blocker,這幾件事交代得出來就行。

Long-running Goal Control Loop

Figure 2|長時間 Goal 的控制迴圈。

如果 Goal 還是「把 auth client 遷移完」,Codex 卻做到一半開始順手改 session architecture,這時用 Steer 把範圍拉回來就好。Session model 不動,繼續處理 target migration。終點沒變,只是這一段走偏了。[2]

如果 product decision 已經改成長期保留兩套 client,情況就不同了。原本的 Goal 是完成 migration,現在要做的是 dual-stack architecture。繼續在舊 thread 裡補「改成……」「剛剛那個先不要……」,幾輪之後連人都得翻 transcript 才知道哪一句才算數。停下來,把新的終點寫清楚,再從那個 objective 繼續會乾淨很多。

這個 migration 最後還是看 parity、tests、diff,以及 legacy path 到底有沒有收乾淨。[1] 花了幾個小時、改了多少檔案,只能說明 Codex 做了很多事。

Finish line 還寫不清楚,或中間連一個能驗的 checkpoint 都切不出來,就先把 task 縮小,把缺的決定補完。等「做到這裡就可以停」真的寫得下來,再讓它長跑。

參考資料

  1. OpenAI, ChatGPT Release Notes — Codex updates: richer context, goal mode, browser improvements, and remote locked use, 2026-05-21. https://help.openai.com/en/articles/6825453-chatgpt-release-notes
  2. OpenAI, ChatGPT & Codex changelog, Goal Mode entries through 2026-06-15. https://developers.openai.com/codex/changelog
  3. OpenAI Academy, Codex for Faculty and Researchers — Follow Along Guide, 2026-06-09. https://academy.openai.com/public/clubs/higher-education-05x4z/resources/codex-for-faculty-and-researchers-follow-along-guide-2026-06-09
  4. OpenAI Codex GitHub, /goal mode repeatedly emits dangerous-operation confirmation prompt and consumes quota, issue #22245, collaborator clarification on Goal continuation and blocker completion definitions, 2026-05-12. https://github.com/openai/codex/issues/22245
  5. OpenAI Codex GitHub, Plan mode makes active /goal look stuck because continuation is suppressed silently, issue #20656, collaborator clarification, 2026-05-13. https://github.com/openai/codex/issues/20656