Why Your DeepSeek Harness Agent Stops: It's Not a Bug, It's Authorization
DeepSeek Harness uses three distinct continuation mechanisms—Goal, Ralph, and Workflow—each with explicit trade-offs: Goal requires human resume due to non-persisted activation, Ralph runs fresh sessions with shared workspace, and Workflow lets models write orchestration scripts in isolated worker threads.
Introduction: The Agent That Won't Move
You set a goal in DeepSeek Harness (DSH), the agent runs a few rounds, then stops. Restarting the session leaves the goal marked active in the status bar, yet the agent does nothing. This is not a bug; it is a deliberate design choice. The article explains that a goal in DSH is merely a persisted state, not a scheduler. The actual driver that makes the agent work is a separate package called goal-round-driver, and automatic continuation must be explicitly enabled.
Two Orthogonal Switches
The goal mechanism relies on two independent switches:
Persistent phase : active / paused / blocked / complete — stored in the session log and survives restarts.
Process-local activation : armed / disarmed — lives only in the current process and is never persisted.
On every session start ( agent/session-start) the system executes disarm (source: index.ts lines 255–257). Therefore, restarting a session always clears the continuation permission. The agent is not broken; it simply lacks authorization to continue. The only way to resume is a human issuing /goal resume or the model invoking the resume tool.
The create operation starts armed, but only when a direct human message is present ( requireDirectHuman). Creating a goal equals explicit human authorization; restarting a session does not.
DSH's Goal is safety-first over smoothness: the rejected alternative of persisting activation was dismissed because the designers preferred an extra resume</click> over letting an agent self-resume invisibly.</blockquote> <h2>Three Parallel Continuation Mechanisms</h2> <p>DSH provides three distinct mechanisms for "continuous work", each solving a different orthogonal problem:</p> <ul> <li><strong>Goal</strong> — continues within the same session (same conversation memory, same session, round budget).</li> <li><strong>Ralph</strong> — starts a brand-new sub-session with no conversation seed, preserving only the shared workspace and a bounded handoff report.</li> <li><strong>Workflow</strong> — lets the model write a JavaScript orchestration script that fans out dozens or hundreds of child agents in parallel.</li> </ul> <p>The following comparison captures their core differences:</p> <ul> <li><strong>What problem they solve</strong>: Goal — goal persistence, session continuity, round budget; Ralph — context pollution, agent confusion; Workflow — large fan-out, parallel orchestration.</li> <li><strong>How they "continue"</strong>: Goal — schedules next Goal Round in same session; Ralph — launches a fresh child session with only the previous bounded report; Workflow — does not continue; the script orchestrates everything in one run.</li> <li><strong>Who pays the cost</strong>: Goal — human (must authorize resume after restore); Ralph — amnesia (uncommitted reasoning disappears); Workflow — model acts as script author + each run consumes a worker thread.</li> </ul> <p>The decision criterion is simple: <strong>decide what you want to survive</strong>. If conversation memory must survive, use Goal. If workspace artifacts must survive, use Ralph. If the parallel orchestration structure must survive, use Workflow.</p> <h2>Goal: Same-Session Continuation with Human Guardrails</h2> <h3>Terminology</h3> <p>A <strong>Goal Round</strong> is "an accepted continuation cycle for the current goal. The same-session driver materializes it as a goal-triggered round that may contain zero or more steps; unrelated human rounds in the same session do not consume the Goal Round limit." Key points: <em>same session</em> and <em>human rounds don't count</em>.</p> <h3>State Machine</h3> <p>Four phases plus seven verbs (<code>create/edit/pause/resume/complete/block/clear ). Three critical transitions: pause : only from active to paused , simultaneously disarms — a true stop. block : only from active to blocked ; all stop reasons (budget exhausted, execution error, need human input) share this single phase, with the reason encoded in a stable code field. resume : can restore active , paused , or blocked , but refuses if the round budget is exhausted. Driver Scheduling: Reserve Then Admit When the agent is idle, the goal is active and armed , and budget remains, the driver reserves the next Goal Round number and enqueues a prompt with that round info. When the agent actually enters that step, the driver re-validates the reservation: claimed, not superseded by a goal revision, content unchanged. Rejected rounds (goal changed mid-flight, reservation expired) do not consume a round number. Budget is hard: default maxGoalRounds = 256 , counting only admitted goal rounds (not tokens, money, time). Human messages and rejected rounds are excluded. The author interprets this as a proxy for "model history budget." Session Log as Single Source of Truth Every goal change appends a persistent goal/change event. Replay strictly validates: continuous revisions, legal phase transitions, consecutive round numbers. Any corruption causes the entire goal access to fail, not skip. Crucially, the projection only reflects the persistent phase; activation is deliberately absent from the projection. Hence "replay shows active" does not equal "auto-continue allowed" . Asymmetric Control The model cannot resume a paused goal — the tool layer rejects with error GOAL_TOOL_RESUME_PAUSED ("the model cannot resume a paused goal; the user must resume it"). Paused is a human-only recovery path. Humans can pause (only when active) or clear (any non-complete goal) without the "3 consecutive rounds" mechanical threshold that constrains the model's autonomous block (guarded by GOAL_TOOL_BLOCK_THRESHOLD ). Goal's cost summary: continuation entirely built on human authorization; restore/fork requires human resume; paused only human-recoverable; no implicit retries for transient failures. The four packages in the goal domain ( goal , tool-goal , command-goal , goal-round-driver ) are at version 0.1.5-rc.2 . Ralph: Continue but Forget Everything When the problem is the opposite — the agent gets more confused the longer it runs — Ralph provides a fresh agent per round that remembers nothing of previous conversations. Ralph Round Definition A Ralph Round is "a fresh sub-session in the Ralph loop. The sub-session receives no conversation seed from the parent or prior sub-sessions." This mirrors Goal: Goal Round = next round in same session; Ralph Round = new sub-session each round. Cross-Round Transfer Two artifacts persist across rounds: Shared workspace (long-term memory and source of truth, used by all rounds). A bounded Ralph handoff — a structured report with status, summary, evidence, next steps, blockers, capped at 16,384 characters, all five fields mandatory, no extra fields allowed. The glossary states it "supplements the shared workspace, not replacing its authority." Fixed Deployer-Owned Script The Ralph loop is not written by the model; it is a fixed script owned by the deployer (submitted via ctx.workflowEngine.start , mounted on the workflow engine). The glossary calls it a "tool policy", not a general workflow script. The model only supplies objective data ( objective , maxRounds ); it cannot alter the loop, schema, or provider routing. The tool docs explicitly state it "will not add Ralph mode or a fresh agent loop to the agent-loop; the same-session goal domain remains independent." Differences from ordinary Workflow: script ownership (deployer vs model) and child-agent shape (exactly one fresh child agent per round, no fan-out vs free orchestration fan-out). Known Limitations Uncommitted conversation reasoning disappears after each child agent ends. Completion and blocking are self-reported by the worker ("Ralph worker reported completion after N rounds") — no independent evaluator verifies true completion. No retry on failure: a failed round returns the failure round and the last successful handoff, then stops. Foreground only: no background collection, no checkpoints, no recovery. Thus Ralph's continuation logic is counter-intuitive: it continues the workspace, not the memory . The new agent forgets what was said, but the artifacts produced remain in the workspace; the previous report is merely "for reference, workspace is authoritative." Default maxRounds = 256 , which is also the deployment ceiling because it is fed directly into the engine's maxTotalAgents gate; the model's value can only lower it. Interestingly, Goal's default budget is also 256 — the author suspects a shared budget philosophy but notes the source says it could be coincidence. Workflow: Model Writes Script, Script Only Coordinates For tasks that are inherently parallel (audit dozens of files, split a migration into 100 independent steps), sequential continuation is inefficient. Workflow takes a radical stance: let the model write the orchestration script . Script Constraints The engine "will never evaluate the script text to obtain" meta / args — they are data, not code. The script has no filesystem, network, timers, or Node.js APIs. The capability constraint: "the agents do the work, the script only coordinates them." A revealing source-code detail: a detector flags scripts that start with export const meta — the model's likeliest authoring slip — and errors with the correct pattern. Isolation in Worker Threads The script runs inside a worker_threads isolate. This is usability isolation, not a security boundary . Docs: "This isolation can limit availability failures, but is not a security boundary; truly untrusted scripts need a separate process or container." Practical benefits: Infinite loops or synchronous spins burn CPU only in the worker, not the harness. If the script ignores cancellation signals, it is forcibly terminated via worker.terminate() after disposeGraceMs = 5000ms , so the caller never hangs indefinitely. Environment credentials are stripped: the worker starts with a sanitized env; secrets in process.env do not cross the boundary. A backstop limit: single-run child-agent total cap defaults to 1000; the model's value can only decrease it, never increase. Cost is explicit: "each run pays for a worker thread" — no pool, no warm-up, no cross-run cache. No cross-run state either: foreground only, no checkpoints, no recovery, and observer events deliberately omit result values. Synchronous Rejection vs Result Settlement The dividing line is whether a run has been created. Four pre-flight errors (invalid meta, script parse failure, unregistered provider, illegal limit) throw synchronously before worker creation. Once a run is returned, all subsequent failures resolve through result.stopReason ( completed , cancelled , error ); the result promise never hangs forever. The JSDoc for engine.start() states: "Throws WorkflowError synchronously (META_INVALID for malformed meta, SCRIPT_PARSE for non-compiling body) for a request that cannot begin; once a run is returned, every failure resolves through result.stopReason instead." Workflow's "non-continuation" stance is equally clear: the tool blocks the parent round until the entire workflow settles; the model sees only the final result, "never the intermediate child-agent messages." Decision Framework: Choose What Must Survive After dissecting the three mechanisms, the article returns to the core judgment: continuous work is a decision problem, not a mechanism problem. The criterion: what do you want to keep alive? Conversation memory must survive → Goal. Goal persists the goal, the session, and the round budget; every step requires human authorization. Workspace artifacts must survive → Ralph. Forgets the conversation, keeps the artifacts; each round gets a fresh perspective. Parallel orchestration structure must survive → Workflow. Model authors the script once; worker thread isolates execution. Each mechanism also has explicit "do not use" scenarios (evidence from system prompts and README): Goal : paused goals can only be resumed by humans; model resume is rejected ( GOAL_TOOL_RESUME_PAUSED ). Do not expect the model to self-resume a stopped goal. Ralph : tasks requiring continuous reasoning or context dependency are unsuitable — no seed means no memory; what was said last round truly does not exist this round. Workflow : for one or two delegations, prefer plain subagent calls (system prompt: "For one or two delegations, prefer plain subagent calls"). Paying a worker thread for two small tasks is not worth it. Plan/todo are not a fourth continuation mechanism. Plan is a pre-execution human approval gate that only toggles whether a planning instruction is included in the request; it adds a read-only status event, launches no child agents, drives no loops, creates no workers. Todo provides progress visibility and parallel discipline via whole-table replacement and log persistence; it drives no execution and blocks no steps. Neither holds scheduling authority to continue work. Architecture: Independent Plugins with Hard Boundaries The three mechanisms exist as independent plugins in the codebase: the goal domain has zero references to plan/todo (grep evidence); tool-ralph docs state "the same-session goal domain remains independent"; goal-round-driver says "does not do Ralph-style independent attempts (that workflow belongs to a separate plugin layer)." Complexity is not centralized in a single scheduler but distributed across plugins, each with its boundaries frozen in code. The system's self-description — "this isolation can limit availability failures, but is not a security boundary" — applies equally to the three continuation mechanisms: each honestly labels its own costs, and none pretends to run unsupervised to completion.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Shuge Unlimited
Formerly "Ops with Skill", now officially upgraded. Fully dedicated to AI, we share both the why (fundamental insights) and the how (practical implementation). From technical operations to breakthrough thinking, we help you understand AI's transformation and master the core abilities needed to shape the future. ShugeX: boundless exploration, skillful execution.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
