How DeepSeek-Reasonix Goal Mode Pursues Long-Running Objectives Until Completion

Goal mode is a finite-state machine that continuously injects the objective into the model's prompt each turn and parses structured status markers to decide whether to continue working, request user intervention, or finalize completion.

DeepSeek-Reasonix implements a sophisticated Goal mode that enables autonomous pursuit of complex, multi-turn objectives without human intervention. Unlike standard chat sessions that terminate after a single response, this system maintains persistent state across turns using a dedicated finite-state machine (FSM) that tracks progress, handles blockers, and ensures objectives reach completion. The implementation spans several core files under internal/control/, with the primary logic residing in goal.go, input.go, and controller.go.

The Goal Mode Architecture

Goal mode operates as a dedicated finite-state machine called goalMachine that stores the current objective, its execution status, turn counters, and persistence logic. The architecture separates concerns across four main components to maintain clean boundaries between state management, prompt generation, and control flow.

Core Components

  • internal/control/goal.go: Implements the goalMachine FSM, including the advance method that processes status markers and the buildStateLocked function for persistence.
  • internal/control/input.go: Handles prompt construction via activeGoalBlock, which inserts the goal context into every model request, and contains parseGoalStatusMarker for extracting status signals from responses.
  • internal/control/port.go: Exposes the Goals interface with methods like Goal(), GoalStatus(), and SetGoalWithResearchMode that the rest of the server uses to query or mutate goal state.
  • internal/control/controller.go: Orchestrates the main loop, drives goalMachine.advance each turn, and manages session lifecycle including loading persisted goal states via loadGoalState.

Setting and Initializing Objectives

When a user issues /goal <objective> or /goal --research …, the system initializes the FSM through Controller.SetGoalWithResearchMode. This call stores the objective text and research mode preference, resets all counters, and prepares a persisted goal-state file.

In internal/control/goal.go, the goalMachine.set function (lines 31-45) handles the initialization:

// Reset FSM state and prepare persistence
goalMachine.set("Investigate and fix the intermittent timeout bug", control.GoalResearchAuto)

The function clears previous turn counts, resets blocked-status counters, and establishes the goalStatePath pointing to <session>.goal-state.json for crash recovery.

Prompt Injection and the Active-Goal Block

Every turn, the controller builds the model prompt by prepending an activeGoalBlock when a goal is active. Located in internal/control/input.go (lines 90-106), this block ensures the model never loses sight of the objective.

The block includes:

  • The opening delimiter <active-goal>
  • Instructions describing Goal mode semantics
  • The exact marker format required: [goal:continue], [goal:complete], or [goal:blocked:<reason>]
  • Auto-Research protocol instructions when applicable
b.WriteString(activeGoalOpen)                    // "<active-goal>"
b.WriteString("Goal mode: pursue this goal autonomously…")
b.WriteString("[goal:continue], [goal:complete] or [goal:blocked:<reason>]")
b.WriteString(activeGoalClose)                   // "</active-goal>"

If the goal qualifies for Auto-Research—determined by isAutoResearchGoal heuristics or explicit flags—the block also contains the full autoResearchGoalInstructions telling the model where to store artifacts and how to handle stale exploration.

Status Markers and Turn Evaluation

At the end of each turn, the model must emit exactly one structured marker. The parseGoalStatusMarker function in internal/control/input.go (lines 49-68) scans the assistant's reply from the newest line upward to extract:

  • [goal:continue] – Indicates ongoing work; the FSM records the turn and proceeds.
  • [goal:complete] – Signals the model believes the objective is finished.
  • [goal:blocked:<short reason>] – Reports the model requires user input to proceed.
// After the model outputs a reply, the controller extracts the marker:
status, reason, ok := control.ParseGoalStatusMarker(replyText)
if ok && status == control.GoalStatusComplete {
    // The FSM will now run self-check or finalize the goal.
}

The Goal FSM Advance Logic

The heart of Goal mode resides in goalMachine.advance (lines 92-124 in goal.go). The controller packages the parsed marker, tool usage status, gathered TODO items, and readiness checks into a goalAdvanceInput, then invokes this method to determine the next state.

The FSM handles several distinct situations:

Completion Validation When receiving [goal:complete], the FSM verifies whether any TODOs remain open or if readiness checks fail. If incomplete work exists, it blocks finalization and returns an intercept message via formatIncompleteTodos. In strict mode, it injects a goalSelfCheckTurn before allowing completion.

Block Detection If [goal:blocked:<reason>] appears, the FSM increments a blocks counter. After three consecutive identical blocks, it transitions to GoalStatusBlocked and persists the blocking reason.

Idle Detection The FSM tracks tool call activity. If the assistant produces maxGoalIdleTurns (default 2) consecutive turns without tool calls, the system injects a reminder demanding progress or explicit blockage declaration.

Turn Limits After maxGoalAutoTurns (default 50), the FSM automatically forces a blocked status to prevent infinite loops.

The advance method returns a goalAdvanceResult containing a notice string (for intercept messages) and a cont boolean indicating whether to continue the session.

Persistence and Session Recovery

Goal mode survives application restarts through JSON serialization. The buildStateLocked function (lines 80-89) serializes the goalState struct, while writeState (lines 98-112) writes to <session>.goal-state.json.

When the controller starts, Controller.loadGoalState in internal/control/controller.go restores the FSM from disk, allowing sessions to resume exactly where they left off—including turn counts, blocked reasons, and the original objective text.

Auto-Research Protocol Integration

For long-horizon tasks, Goal mode integrates the Auto-Research protocol. The shouldUseAutoResearch function evaluates heuristics in isAutoResearchGoal (strong keywords, phase patterns, or explicit /goal --research flags). When enabled, the active-goal block appends detailed instructions directing the model to:

  • Store intermediate artifacts under .reasonix/autoresearch/<task-id>/
  • Increment stale_count and pivot strategies after repeated failures
  • Cease autonomous digging after thresholds and request user input
ctrl.SetGoalWithResearchMode("Refactor the payment module", control.GoalResearchOn)

Accessing Goal State from Client Applications

External interfaces query goal status through the Goals interface. For example, the desktop TUI checks status in desktop/tabs.go (line 858):

goalMode := strings.TrimSpace(m.ctrl.Goal()) != "" && m.ctrl.GoalStatus() == control.GoalStatusRunning

Primary interaction methods include:

goal := ctrl.Goal()            // Returns current objective text
status := ctrl.GoalStatus()    // Returns "running", "complete", "blocked", or "stopped"

Both methods forward to goalMachine.snapshot and goalMachine.statusForDisplay in goal.go, providing real-time visibility into autonomous operation progress.

Summary

  • Goal mode maintains persistent objectives across turns using a finite-state machine (goalMachine) that tracks execution state, turn counts, and blocking conditions.
  • Active-goal blocks inject the objective and protocol instructions into every model prompt via activeGoalBlock in input.go, ensuring continuous focus.
  • Structured markers ([goal:continue], [goal:complete], [goal:blocked:<reason>]) extracted by parseGoalStatusMarker drive the FSM transition logic.
  • Safety guardrails include idle detection after 2 turns, hard limits at 50 turns, and three-strike blockage detection to prevent infinite loops.
  • Crash recovery persists state to <session>.goal-state.json through buildStateLocked and writeState, enabling session restoration via loadGoalState.
  • Auto-Research integration automatically engages for complex tasks, providing file-system workspace and pivot heuristics while maintaining goal-oriented autonomy.

Frequently Asked Questions

How does Goal mode prevent infinite loops during autonomous operation?

The FSM enforces a hard limit of maxGoalAutoTurns (default 50) after which it automatically transitions to GoalStatusBlocked. Additionally, idle detection monitors tool call activity; if the model produces two consecutive turns without tool usage, the system injects a reminder to make progress or declare blockage. These mechanisms ensure that unproductive cycles terminate rather than consume resources indefinitely.

What happens when the model encounters a user-dependent decision during Goal mode?

When the model emits [goal:blocked:<reason>], the FSM increments an internal counter tracking consecutive blocks. After receiving three identical blockage signals, the system transitions to GoalStatusBlocked, persists the reason, and pauses autonomous operation—allowing the user to provide necessary input before resuming pursuit of the objective.

Can Goal mode survive application restarts or crashes?

Yes. The FSM serializes its complete state—including the objective text, turn count, blocked status, and accumulated metadata—to a JSON file at <session>.goal-state.json via writeState after every significant transition. On startup, Controller.loadGoalState deserializes this file, restoring the exact execution context and allowing the session to continue where it left off.

How do I enable Auto-Research for complex debugging or implementation tasks?

Invoke SetGoalWithResearchMode with the GoalResearchOn or GoalResearchAuto parameter. The system evaluates isAutoResearchGoal heuristics (or respects the explicit flag) and, when positive, appends autoResearchGoalInstructions to the active-goal block. This instructs the model to store artifacts in .reasonix/autoresearch/<task-id>/, track stale counts, and pivot strategies after repeated failures while maintaining focus on the long-running objective.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →