Inside the Codex CLI /goal Runtime Architecture
메뉴

AI Agent

Inside the Codex CLI /goal Runtime Architecture

Thread goals, continuation prompts, and completion checks as runtime architecture.

Inside the Codex CLI /goal Runtime Architecture hero image

Viewthread_goals, continuation runtime, and completion audit at the code level

In Part 1, we looked at Codex CLI/goalfrom the user's perspective. In this article, we look at the internal structure.

The key is simple.

# Reading Guide: The blocks below are examples of commands, state flows, or templates./goal is not a single command.It is a function that combines target state storage, app-server API, model tool, runtime continuation, and TUI control.

This article was written based on Codex GitHub PR and publicly available source files. This is a soon-to-be-released feature, so actual implementation may vary in future versions.

Analysis base date: 2026-05-02 Base version: Codex CLI0.128.0 Main reference materials: OpenAI Codex changelog, GitHub PR #18073–#18077,thread_goalsmigration,continuation.md,budget_limit.md


Key takeaways

  • /goalis a five-layer function leading to TUI command to app-server API to model tools to core runtime to state DB.
  • The goal status is stored in thethread_goalstable, and the status is limited toactive,paused,budget_limited, andcomplete.
  • The model tool cannot manipulate goals arbitrarily.update_goalis limited to completion processing, and pause/resume/clear/budget-limited transitions remain under user or runtime control.
  • The core runtime processes turn start, tool completion, turn finish, interrupt, resume, and idle continuation throughGoalRuntimeEvent.
  • The continuation prompt asks you to perform a completion audit based on the “current actual state” before completion.
  • From a good agent design perspective, the key to/goalis evidence event-driven continuation + audit + budget guard, notwhile true.

1. Overall structure: View in 5 layers

Based on the code,/goalis close to the structure below.

# Reading Guide: The blocks below are examples of commands, state flows, or templates.TUI /goal commandapp-server thread/goal APImodel tools: get_goal / create_goal / update_goalcore runtime: continuation / accounting / interrupt / resumestate DB: thread_goals table

Each layer has a different role.

layerrolekey points
TUIUI for users to create, stop and erase/goalCommand and status display
app-serverAPI where the client controls the thread goal stateget/set/clear, notification, resume snapshot
model toolsA tool that allows the model to view, create, and complete goalsPermission restrictions are important
core runtimeContinue, accounting, interrupt, resume processingCentral to creating real “keeps going”
state DBSave goal objective/status/usageThread-level persistence

Looking at this structure, it is clear that/goalis not simply a “prompt telling the model to continue.” The target state is in the DB, and the runtime updates the state according to the turn life cycle.


2. State DB:thread_goalstable

At the very bottom is thethread_goalstable. On a public migration basis, this table stores the following information:

columnmeaning
thread_idThread identifier with goal
goal_idIdentifier of the goal itself
objectiveUser-specified goals
statusOne ofactive,paused,budget_limited,complete
token_budgetOptional token budget
tokens_usedCumulative token usage during goal execution
time_used_secondsAccumulated time during goal execution
created_at_mscreation time
updated_at_msupdate time

If you write it as a pseudo type, you can see it like this.

// Reading Guide: This is not an actual API, but pseudocode that explains the structure.type ThreadGoal = {  thread_id: string  goal_id: string  objective: string  status: "active" | "paused" | "budget_limited" | "complete"  token_budget?: number  tokens_used: number  time_used_seconds: number  created_at_ms: number  updated_at_ms: number}

The important thing here isthread_id. A goal is not a simple memory flag, but is attached to thread state. So it can be connected to functions like resume, reconnect, and app-server snapshot.

Another important one isgoal_id. According to the description of PR #18073, stale update protection has been included. In other words, it is a device that prevents old goal updates from overwriting new goals.

# Reading Guide: The blocks below are examples of commands, state flows, or templates.problem:- Goal A is in progress.- The user replaces it with goal B.- The goal A update that arrives late overwrites the state of goal B. solve:- Check expected goal_id when updating.- If it is different from the current goal_id, it is considered a stale update and blocked.

This protection is important in AI agent runtime. This is because when multiple async tasks, tool results, and user mutations are mixed, “late-arriving updates” can break the state.


3. App-server API: thread goal control plane

The second layer is the app-server API. PR #18074 explains that the following RPC and notification were added to the v2 API.

# Reading Guide: The blocks below are examples of commands, state flows, or templates.RPC:- thread/goal/get- thread/goal/set- thread/goal/clear Notification:- thread/goal/updated- thread/goal/cleared

The reason this API is needed is because the client needs to reliably read and control the goal state.

API elementsrole
thread/goal/getCheck the goal status of the current thread
thread/goal/setSet goal or change state
thread/goal/clearremove goal
thread/goal/updatedNotify the client of goal changes
thread/goal/clearedNotify the client of goal deletion
resume/snapshot wiringAllows the reconnected client to view the current goal status.

With this layer, not only TUI but also other clients can see the same goal status. In other words,/goalis not a TUI-specific hack, but a structure that handles materialized thread goals through the app-server.


4. Model tools: Limited model permissions

The third layer is the model-facing tool. According to PR #18075, there are three goal-related tools:

# Reading Guide: The blocks below are examples of commands, state flows, or templates.get_goalcreate_goalupdate_goal

This is where the design gets interesting. The model does not allow unlimited manipulation of the goal.

ToolAllowed Roleslimits
get_goalCheck current goalread center
create_goalCreate an explicitly requested goalRestrict creation to only when there is no existing goal
update_goalGoal completion processingLimited to center on completion

The PR description explains that thepause,resume,clear, andbudget_limitedtransitions are not handled by the model at will, but are left user- or runtime-controlled.

This design is important.

Giving all state control to the model can cause problems like this.

# Reading Guide: The blocks below are examples of commands, state flows, or templates.- The model pauses itself to avoid work.- The model arbitrarily releases the budget exceeding state.- The model clears the goal created by the user.- Marked as complete even though it is not completed.

So/goalallows the model to perform tasks and declare completion, but separates user control from runtime control.

# Reading Guide: The blocks below are examples of commands, state flows, or templates.Model permissions: lookup, explicit creation, completion processingUser permissions: pause, resume/unpause, clear, replacementruntime permissions: budget_limited, accounting, continuation scheduling

This separation of rights is worth referring to when creating an agent system.


5. Core runtime: continuation state machine

The fourth layer is the most important. PR #18076 views long-running goals as a core runtime concern, not as a client. This is because the core manages turn lifecycle, tool completion boundaries, interruptions, resume behavior, and token usage.

Looking at thegoals.rsannotation in the public code, this module connects the core session and the state DB goal table and is responsible for goal mutation verification, protocol conversion, goal-update event issuance, and lifecycle hook.

Key events can be viewed as follows:

# Reading Guide: The blocks below are examples of commands, state flows, or templates.GoalRuntimeEvent- TurnStarted- ToolCompleted- ToolCompletedGoal- TurnFinished- MaybeContinueIfIdle- TaskAborted- ExternalMutationStarting- ExternalSet- ExternalClear- ThreadResumed

Summarized in pseudocode, it is as follows.

// Reading Guide: This is not an actual API, but pseudocode that explains the structure.on TurnStarted:  capture token usage baseline  if current thread has active goal:    mark goal active for this turn on ToolCompleted:  account token/time usage  reset no-tool continuation suppression  if token budget exceeded:    mark goal as budget_limited    inject budget wrap-up steering on TurnFinished:  account final usage  if this was a continuation turn and tool_calls == 0:    suppress next automatic continuation on MaybeContinueIfIdle:  if session is idle and active goal exists:    start continuation turn on TaskAborted with interrupt:  account usage  pause active goal on ThreadResumed:  reactivate paused goal outside plan mode

Here, the true nature of/goalis revealed. The reason Codex “appears to continue working” is not because the model runs in an infinite loop by itself, but because it schedules a continuation turn while the core runtime is idle.

# Reading Guide: The blocks below are examples of commands, state flows, or templates.active goal exists+ session is idle+ not suppressed+ budget not exhausted= start continuation turn

6. Continuation prompt: The key to completion auditing

continuation.mdtemplate is the key to/goalquality.

This prompt instructs you to continue executing the active thread goal first. At the same time, it specifies that the objective should be treated as “user-provided data.” In other words, the goal statement is not promoted like a system instruction.

Also, the following information is included in each continuation.

# Reading Guide: The blocks below are examples of commands, state flows, or templates.Time spent pursuing goalTokens usedtoken budgetTokens remaining

The most important part is the completion audit. The prompt asks you to do the following before declaring completion:

requestmeaning
Reorganize objectives into concrete deliverables/success criteriaConvert your goals into testable form
Mapping all explicit requirements to evidence checklistAvoid missing requirements
View real evidence including files, command output, test results, PR status, etc.Judge based on current status, not words
Do not complete with proxy signal alone“Passing the test” is only evidence if it covers the entire goal
If you are uncertain, keep working instead of completing.Prevent premature completion in ambiguous states

This part is very important in AI agent design.

This is how a bad agent loop ends:

# Reading Guide: The blocks below are examples of commands, state flows, or templates.One test passedto It's probably okay→ complete

A good goal runtime should end like this.

# Reading Guide: The blocks below are examples of commands, state flows, or templates.List your target requirementsto map each requirement to actual evidenceto Check missing/unverified itemsto complete if all are metto or select the next concrete action

This is the difference between/goaland a simple repeat prompt.


7. Budget limit: soft stop design

/goalhas the concept of token budget. Public migrations includetoken_budgetandtokens_used, and runtime PR explains that token budget exhaustion is treated as a soft stop.

The important thing is that active turns are not forced to abort when the budget is reached. Instead, we mark the goal asbudget_limitedand inject wrap-up steering.

The intention ofbudget_limit.mdis as follows:

# Reading Guide: The blocks below are examples of commands, state flows, or templates.- The active thread goal has reached the token budget.- Objective is treated as user-provided data.-Do not start new substantive work.- Organize progress, remaining tasks, blockers, and next steps.- Do not call update_goal complete unless it is actually completed.

This is a good design. Just because the budget is over doesn't mean the goal is complete.

# Reading Guide: The blocks below are examples of commands, state flows, or templates.budget exhausted!= goal complete

If the budget limit is designed incorrectly in a practical agent, two problems arise.

bad designproblem
Immediate hard abort when budget is exceededRemaining tasks and status are not communicated to users
Treat budget exceedance as completeUnfinished tasks appear complete

Codex's direction is somewhere in between.

# Reading Guide: The blocks below are examples of commands, state flows, or templates.over budgetto budget_limited state transitionto prevent starting new tasksto Summary of progress and reporting of remaining workto complete only when it is actually completed

8. Loop guard and safety device

The most dangerous thing about long-running goals is endless repetition./goalcontains devices to reduce this.

8.1 No-tool continuation suppression

PR #18076 explains that automatic continuations are suppressed when the continuation turn ends without a tool call.

The meaning is this:

# Reading Guide: The blocks below are examples of commands, state flows, or templates.Start continuation turnThe to model just talks without actually reading/editing files/executing commands.→ tool_calls == 0to suppress next automatic continuation

This device is important. Otherwise, your model can get stuck in a loop where it just says things like “I’ll keep going.”

8.2 Interrupt pause

When the user stops, the active goal is paused. This is a structure to prevent the goal from continuing even if the user stops.

# Reading Guide: The blocks below are examples of commands, state flows, or templates.user interrupt→ active goal accounting→ goal status paused

8.3 Resume auto-reactivation

According to the description of PR #18076, when thread resumes, an action has been taken to automatically reactivate paused goals if they are not in plan mode. In other words, it treats interruption and resumption as part of the goal lifecycle.

8.4 Stale goal_id protection

In the state layer, there is stale update protection based ongoal_id. Prevents old updates from overwriting new goals.

8.5 Objective privilege separation

The continuation prompt treats the objective as user-provided data rather than a “higher-priority instruction”. This is a structure to prevent it from being promoted to a system/developer instruction even if the user enters a strong command in the goal.


9. Apply to your own Agent design

The most important thing to learn from/goalis the separation of “auto-repeat” into runtime events.

Bad implementations usually end up like this.

// Reading Guide: This is not an actual API, but pseudocode that explains the structure.while (true) {  const result = await agent.run(goal)  if (result.done) break}

This method is simple but risky.

# Reading Guide: The blocks below are examples of commands, state flows, or templates.- The completion judgment is weak.- Cost restrictions are poor.- Difficult to stop/resume.- Difficult to handle user input priorities.- It is difficult to prevent repetition without tool calls.- A previous goal update may overwrite the new goal.

A better structure would be like this:

// Reading Guide: This is not an actual API, but pseudocode that explains the structure.interface GoalRuntime {  state: GoalStateStore  scheduler: ContinuationScheduler  auditor: CompletionAuditor  accounting: UsageAccounting  controls: UserControls  guards: LoopGuards}

The responsibilities of each component are separated.

componentresponsibility
GoalStateStoreSave objective, status, usage, timestamps
ContinuationSchedulerNext turn starts only in idle state
CompletionAuditorMapping requirements and evidence to determine completion
UsageAccountingtoken/time budget accumulation
UserControlspause, resume, clear, replace
LoopGuardsno-tool suppression, stale update protection, interrupt handling

The actual implementation pseudocode can be captured as follows.

// Reading Guide: This is not an actual API, but pseudocode that explains the structure.async function maybeContinueIfIdle(session: Session) {  if (!session.isIdle()) return  if (session.hasPendingUserInput()) return   const goal = await goalStore.get(session.threadId)  if (!goal || goal.status !== "active") return  if (goalRuntime.isContinuationSuppressed(goal.goal_id)) return  if (goal.token_budget && goal.tokens_used >= goal.token_budget) return   await session.startContinuationTurn({    prompt: renderContinuationPrompt(goal),    goal_id: goal.goal_id,  })}

It is recommended that completion judgments be separated by a separate auditor.

// Reading Guide: This is not an actual API, but pseudocode that explains the structure.async function auditCompletion(goal: Goal, evidence: Evidence[]) {  const checklist = buildChecklist(goal.objective)  const coverage = mapEvidenceToChecklist(checklist, evidence)   if (coverage.hasMissingItems()) {    return { complete: false, nextAction: coverage.suggestNextAction() }  }   if (coverage.hasWeakVerification()) {    return { complete: false, nextAction: "collect stronger evidence" }  }   return { complete: true }}

The key is not whether the agent worked hard, but whether the requirements were met with actual evidence.


10. Implementation Checklist

If you are creating your own goal-based agent, it is recommended to check the following.

# Reading Guide: The blocks below are examples of commands, state flows, or templates.Goal State[ ] Place goal_id.[ ] Save the objective.[ ] Limit status to active/paused/budget_limited/complete, etc.[ ] Accumulate token/time usage.[ ] Enable stale update protection. Runtime[ ] separates the turn started/finished events.[ ] Count usage from tool completed events.[ ] The continuation starts only in idle state.[ ] User input takes precedence over continuation.[ ] Pauses the active goal when interrupted.[ ] Restores the goal state when resumed. Completion Audit[ ] Reorganize objectives into success criteria.[ ] Make requirements into a checklist.[ ] Map each item to a file/command/test result.[ ] Do not complete processing with proxy signal alone.[ ] If uncertain, proceed with continue rather than complete. Budget[ ] A token budget can be set.[ ] If the budget is exceeded, it is not processed as complete.[ ] Provides wrap-up in budget_limited state.[ ] Steering so as not to start a new substantive task. User Controls[ ] pause is supported.[ ] Supports resume or unpause.[ ] Clear is supported.[ ] When replacing, distinguish between the existing goal and the new goal. Loop Guards[ ] A continuation without a tool call is not repeated.[ ] Set a long-running command timeout.[ ] Record history to avoid repeating the same failure.[ ] Limit permissions and writable scope.

11. References and uncertainty

References

confirmed facts

  • Thethread_goalstable storesthread_id,goal_id,objective,status,token_budget,tokens_used,time_used_seconds, timestamps.
  • statusis limited toactive,paused,budget_limited,complete.
  • thread/goal/get,thread/goal/set,thread/goal/clearRPC and goal updated/cleared notification have been added to app-server.
  • The model-facing tools areget_goal,create_goal, andupdate_goal, andupdate_goalis limited to the center of completion.
  • The core runtime handles idle continuation, usage accounting, budget limit, interrupt pause, resume reactivation, and no-tool suppression.

Author's interpretation

  • /goalcan be seen as an example of incorporating the “goal-based runtime” of an AI coding agent into a popular product.
  • The most important design point is the completion audit rather than the continuation scheduler.
  • This structure can be applied not only to Codex CLI but also to its own AI Agent, CI repair bot, and long-running coding assistant.

uncertainty

  • As this is a feature immediately after release, CLI help, command alias, and documentation may be subject to change.
  • The compaction failure mode mentioned in GitHub issue #19910 is based on user reports and may be modified in the future.
  • This is based on open source analysis, so internal runtime details or product behavior may vary across versions.

finish

In summary, Codex CLI/goalis not a simple slash command, but a function that configures the agent runtime around the goal state.

The most important lesson is this:

# Reading Guide: The blocks below are examples of commands, state flows, or templates.If you want to run the AI ​​Agent for a long time, do not create a while loop first,Status, events, auditing, budget, and user controls must be designed first.

/goalshows that direction well. It stores goals, continues with runtime events, audits completion with actual evidence, and handles budgets and interrupts as state transitions.

If you are creating your own AI coding agent, this structure is worth referring to. In particular, theGoal State + Evidence Checklist + Continuation Scheduler + Budget Stop + User Controlcombination is a much safer starting point than simple repetition.

댓글

GitHub 계정으로 로그인하면 댓글을 남길 수 있습니다. 댓글은 GitHub Discussions를 통해 운영됩니다.

TOP