返回 CodeWhale
WORKFLOWS_GOAL_PARITY.md
根目录 / docs / design / WORKFLOWS_GOAL_PARITY.md
1 # Workflows and goal mode — parity audit (Grok Build, DeepSeek Harness, Codewhale)
2
3 Date: 2026-08-15. Evidence: the local Grok Build source sync at
4 `/Volumes/VIXinSSD/CW/grokbuild` (SOURCE_REV
5 `e6a67a5408288c98380cd13f3b1fe1fbc01c9f1f`, `crates/codegen/xai-workflow`,
6 `xai-grok-shell/src/session/{goal_*,workflow/*}.rs`), the installed DeepSeek
7 Harness `@deepseek-ai/dsh@0.1.0-rc.6` package READMEs (`dsh-goal`,
8 `dsh-tool-goal`, `dsh-goal-round-driver`, `dsh-command-goal`,
9 `dsh-tool-workflow`, `dsh-workflow`, `dsh-tool-ralph`, `dsh-tool-todo`,
10 `dsh-schedule`) and `config/agent-presets/standard/agent.cordis.yml`, plus a
11 real Codewhale dogfood run (Ollama `qwen3:4b`, isolated home) captured under
12 `scratchpad/wfgoal-captures/` (`g0*-*.txt`, `w0*-*.txt`, `wf-cli-run.log`).
13 Public Grok Build docs found by search:
14 [Developers Digest guide](https://www.developersdigest.tech/blog/grok-build-developer-guide-2026)
15 (`grok goal "…"`, `grok goal status|pause|resume|clear`, `--max-turns`,
16 Arena Mode) — official docs at x.ai/cli returned 404 for the deep pages.
17
18 ## What Grok Build does (from source)
19
20 - Goal mode is a state machine (`GoalTracker`): phases Idle → Planning →
21 Executing; statuses `active`, `user_paused`, `back_off_paused` (run cap),
22 `no_progress_paused` (verifier flagged the same gaps twice), `infra_paused`
23 (turn error), `blocked`, `budget_limited`, `complete`. Unknown persisted
24 statuses restore as `user_paused` — a goal never resurrects as
25 self-driving after a restart. A goal planner, an adversarial "skeptic
26 panel" classifier, a strategist that can restructure after stalls, a
27 summarizer, and a next-step generator sit around it. `/goal status`,
28 `/goal pause`, `/goal resume`, `/goal clear` are native.
29 - Workflows are Rhai scripts (`agent()`, `parallel()`, `phase`, `log`,
30 `budget`, scratch files, `git_diff_since`) with `meta {name, description,
31 whenToUse, phases}`, a call budget (`DEFAULT_AGENT_BUDGET = 128`), a
32 request-hash journal that replays completed calls so an edited or resumed
33 workflow does not repeat work, persisted run manifests (up to 128 restored
34 runs), pause kinds `user|back_off|no_progress|verification|infra`, saved
35 workflows in `.grok/workflows/*.rhai` (project + user scope, trust-checked
36 paths, name == meta.name), one builtin (`deep-research`), and native
37 `/workflows`, `/workflow resume <name>`, `/workflow stop <name>`,
38 `/workflow review`.
39
40 ## What DeepSeek Harness does (from the installed package)
41
42 - The goal domain is event-sourced session state (`goal/change` events with
43 full snapshots, compare-and-set `{id, revision}`), one current goal, phases
44 active/paused/blocked/complete, `defaultMaxGoalRounds = 256`. Activation
45 (permission to auto-continue) is process-local and never persisted: every
46 session start/fork disarms it and a human `/goal resume` rearms.
47 - The model-facing policy is what makes it enter goal mode readily:
48 "`create_goal` may infer goal intent from a direct human request in any
49 language; do not create a goal for routine single-turn work … Mark
50 complete only when the objective is actually achieved. Mark blocked only
51 after the same blocking condition persists for at least 3 consecutive goal
52 rounds." Creation is only accepted from a direct human turn of a root
53 agent — subagents and non-human producers are rejected at execution.
54 - The round driver queues one retained `<goal_round>` user message per round
55 naming the objective and `round/maxGoalRounds`; human messages never
56 consume rounds; cancellation pauses the goal so it cannot auto-restart.
57 - `/goal` (native command, no model turn) shows objective, phase, rounds and
58 the valid next commands; `/goal <objective>` never replaces an unfinished
59 goal without an explicit clear; `/goal edit|pause|resume|clear`.
60 - Workflows: the model writes a JavaScript script (`agent()`, `parallel()`,
61 `pipeline()`, `phase`, `log`, `args`) run by a worker-thread engine;
62 guidance says to use it "ONLY when the user explicitly asks for a workflow
63 or for large multi-agent orchestration"; foreground collection only, no
64 journaling/resume, no saved or nested workflows, no token budget
65 vocabulary (all stated in the package's Known Limitations). `ralph` runs a
66 fixed fresh-child loop (`maxRounds` 64 in the standard preset);
67 `todo_write` is the standing plan strip; `dsh-schedule` gives durable
68 reminders (`after_seconds`, `at`, `every_seconds` ≥ 5 min).
69
70 ## What Codewhale does today (release candidate 533c530be + integration tip)
71
72 - `/goal <objective> [budget: N]`, `pause|resume|done|blocked|clear`,
73 `declare-hunted`; state Active/Paused/Complete/Blocked with pause reasons
74 `user|backoff|no_progress|usage_limit|budget_limit`, gap-fingerprint stall
75 detection, completion verification (critical/advisory reviews), unlimited
76 continuations by default (`[goal] max_continuations` backstop, like Grok
77 Build's call cap), typed continuation prompt, thread-scoped goal
78 persistence for app-server clients (`thread/goal/*`). Interrupting a turn
79 keeps the goal active (design decision 2026-07-24) and only cancels the
80 auto-continuation timer.
81 - Workflows: JS authoring lowered to a typed `WorkflowSpec` (compile-only
82 subset), `task()/parallel()/pipeline()/phase()/log()/budget/args`, soft-auto
83 launch policy, plan-approval cards, per-run token budgets, worktree write
84 ownership, gates, per-event run journal `.codewhale/workflow-runs.jsonl`
85 with restart reconciliation, live workflow panel + history card,
86 `codewhale workflow run <name|--source-path> --runtime tmux|inline|vm|ci`.
87
88 ## Dogfood findings (before this lane)
89
90 1. `/goal help` created a goal named "help" (no reserved help/status words).
91 2. Bare `/goal` on an empty session spent a model turn asking the model to
92 invent an objective; a 4B local model answered with tool-syntax noise
93 (`g02-goal-bare-nogoal.txt`).
94 3. `/goal` status used bracket tags (`Goal [HUNTING]: …`) and, after Esc, gave
95 no hint that nothing was driving the goal any more.
96 4. `/workflow status` and `/workflow cancel` were routed *through the model*
97 ("Call the `workflow` tool with action `status`…") — a status check cost a
98 model turn and a cancel depended on a busy model obeying; the panel's
99 cancel control pre-filled that same command.
100 5. The `[workflow]` table documented in `docs/AUTOMATIC_WORKFLOWS.md`
101 (`automatic`, `auto_start_read_only`, `require_approval_for_writes`, …)
102 was parsed but ignored: the tool consulted `WorkflowConfigToml::default()`
103 ("Product defaults … when the tool has no live Config handle").
104 6. The example workflows' header says `Run: /workflow run <path>` but the
105 slash command had no `run` verb (it became an objective for the model).
106 7. `create_goal` was gated on "only when the user explicitly asks" — the
107 entry-path difference from DSH.
108 8. A checked-in workflow ran end to end through the CLI with the local model
109 (`wf-cli-run.log`: two children, result `{"a":"hello","b":"world"}`,
110 journal + report written), and the TUI status can now read it.
111
112 ## Matrix
113
114 | Row | Grok Build | DeepSeek Harness | Codewhale | Verdict |
115 | --- | --- | --- | --- | --- |
116 | Authoring | Rhai script + meta; builtins; saved `.grok/workflows` | model-written JS script only | JS compile-only subset + structured `plan` + checked-in `.workflow.js`; `codewhale workflow run` | parity (different surface); saved-workflow *registry* with names is missing — checked-in files exist but no `/workflow list <saved>` |
117 | Triggering | manual `/workflow`, `/workflow resume` | model tool; `dsh-schedule` reminders | manual `/workflow`, soft-auto launch, `codewhale workflow run`, automations (`~/.codewhale/automations`) | parity; scheduled workflow runs deliberately not added here |
118 | Goal definition | `/goal`, planner phase | `/goal`, model-inferred `create_goal` | `/goal`, model `create_goal` — now inferable (this lane) | parity |
119 | Checkpoints / resume | journal replay of completed calls; run manifests; `/workflow resume` | none (documented limitation) | per-event journal + restart reconciliation; no replay-resume | partial (Codewhale ≥ DSH, < Grok Build) — follow-up |
120 | Approvals inside runs | plan-approve loop | tool approvals per child | plan-approval card gated by `[workflow]` (`require_approval_for_writes` / `auto_start_read_only`); session auto-approve still bypasses the card; writes inside a running VM step follow the VM runtime contract | parity |
121 | Progress / state visibility | `/workflows`, `/goal status`, tasks pane | web plan strip, `/goal` | workflow panel, work bar, `/workflow status` (now native), `/goal` (now plain, idle hint) | parity |
122 | Receipts / history | run manifests | session log | `.codewhale/workflow-runs.jsonl`, `/workflow status` lists journaled runs, trophy cards | parity |
123 | Failure handling / retry | pause kinds; strategist restructure | model judgment; ralph rounds | verifier gates, no-progress pause, blocked, `[goal] max_continuations` | parity; auto-restructure (strategist) deliberately absent |
124 | Cancellation | `/workflow stop <name>` native | cancel via signal | `/workflow cancel [id]` native (this lane); Esc cancels children | parity |
125 | Fan-out inside a workflow | `parallel()`, agent budget 128 | `parallel()/pipeline()`, no budget vocabulary | `parallel()/pipeline()`, 16 live / 1000 total, token budget | parity |
126 | Interrupt semantics | Ctrl+C pauses the goal | cancellation pauses the goal | Esc keeps goal active, cancels the timer, `/goal` now says how to continue | deliberately different (2026-07-24 dogfood decision) |
127 | Docs accuracy | — | — | fixed: `/workflow run`, `[workflow]` honored, `/goal` verbs | fixed |
128
129 ## What this lane changed
130
131 - `/workflow status|runs [run_id]`, `/workflow cancel [run_id]`,
132 `/workflow settings`, `/workflow help` are host answers
133 (`crates/tui/src/commands/groups/core/workflow.rs`,
134 `crates/tui/src/tools/workflow.rs::{host_workflow_runs,
135 host_cancel_workflow}`); `/workflow run <path>` launches a checked-in file
136 as-is; `/config workflow` / `/config goal` explain the effective tables.
137 - The workflow tool reads the session `[workflow]` table for approval and
138 admission decisions (`workflow_config_for`). `require_approval_for_writes`
139 gates the start card only: YOLO / session auto-approve still bypasses it,
140 and writes inside a running VM step stay on the VM runtime contract.
141 - `/goal help|?|status`, bare `/goal` prints usage on an empty session, plain
142 status wording (`Goal active: … · elapsed … · continuations N · not running
143 now — send a message or /goal resume to continue`).
144 - `create_goal` guidance now lets the model infer long-running intent from a
145 direct request (DSH policy) and promises a one-line receipt instead of a
146 confirmation question; the runtime shows `Goal set: "…" · /goal shows
147 progress · /goal pause or /goal clear stops it` when the model (or a
148 restored session) introduces a goal.
149
150 ## Follow-ups (not done here)
151
152 - Journal-replay resume for workflows (`/workflow resume <run_id>`): the
153 per-event journal already records every task; the missing piece is a
154 request-hash cache in the driver so completed leaves return their recorded
155 results on re-run (Grok Build `xai-workflow/journal.rs` is the reference).
156 - A saved-workflow registry (`.codewhale/workflows/*.workflow.js` with
157 `meta.name`, project + user scope, trust-checked) so `/workflow run <name>`
158 and `/workflow list` work by name; the CLI already resolves `workflows/`.
159 - Grok Build-style stall handling beyond no-progress pause (strategist
160 restructure, next-step generator) — evaluate after the prefix-cache lane,
161 since both add prompt sections.
162 - Small-context local models: the emergency compaction loop (`estimate ~3272
163 tokens, budget ~1024` on an 8K Ollama route) and the phase strip showing
164 "Context automatically compacting…" for the whole turn were observed but
165 are outside this lane's scope (`g0*` captures).
166
166 lines MARKDOWN