docs(goals): sync the Goal docs with the current runtime - #10785
Conversation
Four statements in the Goal docs no longer match the code. The headless note said ACP still uses the legacy Goal command path. ACP adopted the v3 runtime in QwenLM#8732: it drives the same runtime through the sessionGoalControl extension method and pushes every status change as a session/update notification carrying _meta.goalState. The propose_goal section said the tool refuses in subagents. It is never registered there at all: registerGoalWorkerTools returns early when forSubAgent is set, so a subagent has no get_goal, update_goal, or propose_goal to refuse. The objective guidance gave one 1,200-character figure without saying where it comes from. /goal set and /goal edit do not check length at all; propose_goal caps the objective at 1,500 characters. Both facts now appear, with the 1,200 recommendation kept as guidance because the objective is re-sent on every Goal turn. The introduction implied a verifier runs after every turn. It runs only when the model proposes a terminal status through update_goal; an ordinary turn just records evidence. The /goal row in the command table also listed only two of its six forms.
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
Thanks for this, @qqqys — the four corrections are clearly researched against the code, and the direction is right. The gate has to stop here anyway, because the PR description doesn't follow the pull request template.
What's missing:
## What this PR doesand## Why it's needed— the prose you wrote covers both, it just needs to live under the headings- The
## Reviewer Test Plansubsections:### How to verify(your grep pointers fit perfectly here),### Evidence (Before & After)(N/Ais fine for a docs PR), and the### Tested ontable ## Risk & Scope## Linked Issues— yourRelated: #4228 / #10662references belong there- The
<details>中文说明</details>section with the full Chinese translation of the body
Please fill in the description, then push a new commit or comment @qwen-code /triage to re-trigger triage — it can move to code review from there.
中文说明
@qqqys 感谢这份 PR——四处修正都明显对照过代码,方向没有问题。但门禁必须先停在这里,因为 PR 描述没有按照 PR 模板 填写。
缺少的部分:
## What this PR does和## Why it's needed——你写的正文已经涵盖了这两部分,只需要放到对应标题下## Reviewer Test Plan的子章节:### How to verify(你给的 grep 验证指引正好放这里)、### Evidence (Before & After)(文档 PR 写N/A即可)、以及### Tested on表格## Risk & Scope## Linked Issues——Related: #4228 / #10662的引用应该放在这里<details>中文说明</details>部分,需要完整的中文正文翻译
请补齐描述后推送新 commit,或评论 @qwen-code /triage 重新触发 triage,之后就可以进入代码审查。
— Qwen Code · qwen3.8-max
|
📄 Docs-only change — the automatic review ran at
Reviewed head: 中文说明📄 纯文档变更 —— 自动评审以 |
…eclined The propose_goal section said that on a decline "the model is told only that the Goal was not set, and must not propose it again". The message it describes is unreachable: a declined dialog resolves as a cancel outcome, and the tool scheduler settles the call as cancelled without ever entering the tool's execute(). What the model receives is the scheduler's own cancellation notice. What actually stops it from re-proposing is the tool description, which already tells it the decision will not be reported and the same objective must not be proposed again. The sentence now says that.
qwen-code-dev-bot
left a comment
There was a problem hiding this comment.
Reviewed at head 7de45f0d.
- All four doc corrections verified against the code at this head: the Goal lifecycle now matches the proposal-driven verifier (turns recorded as evidence, verifier judges proposed complete/blocked), the
/goalsubcommand list in commands.md matches the parser surface, thepropose_goalsection now reflects the actual decline contract (model sees only "not approved" and must not re-propose — same wording asPROPOSE_GOAL_NOT_APPROVED_MESSAGE) and thesession_permission_vote-era registration behavior (subagents never offered), and the ACP note namessessionGoalControl/_meta.goalState, both present in the code. - The only standing CHANGES_REQUESTED is the triage bot's template-compliance gate; the description now carries every required section including the Chinese mirror, and the follow-up commit lands the fifth correction — so the gate's stated blocker is resolved, awaiting a triage re-run to flip its own ticket.
- Docs-only diff, CI has no failures. Per the channel convention the call is on the review itself.
yiliang114
left a comment
There was a problem hiding this comment.
Verified all five corrections against the code on main:
- ACP sessions drive the Goal runtime through
sessionGoalControl(acp-bridge/bridge.ts, acp-integration/acpAgent.ts) and surface status viagoalStatein session updates — the legacy-path note was stale. registerGoalWorkerToolsreturns early onforSubAgent(config.ts), so subagents are never offeredpropose_goal— "never offered" is the accurate wording, not "refuses".- The
/goalsubcommand list matches goalCommand (set/edit/pause/resume/clear). - No length cap on
/goal set/editobjectives;propose_goalis capped atPROPOSE_GOAL_OBJECTIVE_MAX_CHARACTERS = 1500(goal-tools.ts:606). - The decline wording matches the tool description ("you will not be told why; do not ask about it and do not propose the same or a reworded objective again").
Docs-only, CI green. LGTM, approving.
|
Released in v0.23.0. |
|
Post-merge review of head Verified
One follow-up worth tracking (minor, non-blocking). The Reviewed with AI assistance. |
What this PR does
Corrects five statements in the Goal documentation that no longer match what the code does, and completes the
/goalrow in the command table. Documentation only; there is no behavior change.The headless note said ACP still uses the legacy Goal command path. ACP sessions moved to the v3 Goal runtime in #8732: they drive the same runtime through the
sessionGoalControlextension method, and every status change reaches the client as asession/updatenotification carrying_meta.goalStaterather than as thegoal_statestream event the surrounding paragraph describes for--output-format stream-json.The
propose_goalsection said the tool refuses in subagents. Nothing refuses, because nothing is registered: the goal worker tool registration returns early for subagents, so a subagent never seesget_goal,update_goal, orpropose_goal.The objective guidance gave a single "roughly under 1,200 characters" figure with no explanation, which reads like an enforced limit.
/goal setand/goal editdo not check length at all, and a model-proposed objective is capped at 1,500 characters. Both facts are now stated, and the 1,200 recommendation is kept as advice with its reason: the objective is re-sent on every Goal turn.The page introduction said an independent verifier checks the transcript after each turn, which suggests a verifier call on every iteration. The verifier runs only after the model proposes a terminal status; an ordinary turn records evidence and continues, and evidence compaction is a separate checkpoint pass.
The same
propose_goalparagraph also said that on a decline "the model is told only that the Goal was not set, and must not propose it again". The message it describes is unreachable: a declined dialog resolves as a cancel outcome and the tool scheduler settles the call as cancelled without ever entering the tool'sexecute(), so what the model receives is the scheduler's own cancellation notice. What actually stops it from re-proposing is the tool description, which already says the decision will not be reported. The code side of that finding is #10787; the sentence is corrected here because this PR already rewrites the same physical line, and splitting the two across separate PRs made them conflict.The
/goalrow in the command table also listed only<condition>andclear, omittingedit,pause, andresume, which the command parser has accepted since Goal v3.Why it's needed
Each of these sends a reader to the wrong conclusion. Someone integrating over ACP would look for a stream event that never arrives. Someone writing an objective would trust a character limit that is neither the real cap nor explained. Someone reasoning about cost would assume a verifier call per turn. The subagent claim is the first item in #10662, verified there by a maintainer.
Reviewer Test Plan
How to verify
No code changes, so nothing to run. Each claim can be checked by reading the code the sentence describes.
packages/core/src/config/config.tsreturns early when the subagent flag is set, beforeget_goal,update_goal, orpropose_goalare registered.PROPOSE_GOAL_OBJECTIVE_MAX_CHARACTERSinpackages/core/src/goals/goal-tools.tsis 1500; the command parser inpackages/cli/src/ui/commands/goalCommand.tsperforms no length check.sessionGoalControlinpackages/cli/src/acp-integration/acpAgent.ts, and the goal state update builder in the ACP message emitter, which sends_meta.goalStateon asession/update.finishTurninpackages/core/src/goals/goal-runtime.tsruns the verifier only when a terminal proposal was recorded.goalCommand.tsacceptsset,edit,pause,resume, andclear.Evidence (Before & After)
N/A — documentation only.
Tested on
Environment (optional)
N/A — no runtime involved. Prettier formatting was applied to the three touched files.
Risk & Scope
Linked Issues
Related: #4228 (Phase 1), #10662, #8732, #10787.
中文说明
这个 PR 做了什么
修正 Goal 文档中五处与代码实现不符的说法,并补全命令表里
/goal一行。纯文档改动,没有行为变化。headless 文档说 ACP 仍走旧的 Goal 命令路径。ACP 会话已在 #8732 迁移到 v3 Goal runtime:它通过
sessionGoalControl扩展方法驱动同一个 runtime,每次状态变化以带_meta.goalState的session/update通知送达客户端,而不是同段落中描述的--output-format stream-json下的goal_state流事件。propose_goal一节说该工具在子代理里会拒绝。实际上没有任何拒绝行为,因为它根本没有注册:goal worker 工具的注册函数在子代理场景下直接返回,子代理从来看不到get_goal、update_goal或propose_goal。目标写法指导只给了一个「大约 1,200 字以内」的数字且没有解释,读起来像是强制上限。实际上
/goal set与/goal edit完全不检查长度,而模型提议的目标上限是 1,500 字。现在两个事实都写清楚了,1,200 作为建议保留并说明理由:目标文本在每个 Goal 轮次都会重新发送。页面开头说每轮结束后独立 verifier 都会检查转录,这让人以为每次迭代都有一次 verifier 调用。实际上 verifier 只在模型提出终止状态之后才运行;普通轮次只记录证据并继续,证据压缩是独立的 checkpoint 流程。
同一个
propose_goal段落还说,用户拒绝时「模型只被告知 Goal 未被设置,并且不得再次提议」。它描述的那条消息不可达:拒绝对话框的结果是 cancel,工具调度器直接把调用结算为 cancelled,永远不会进入工具的execute(),模型收到的是调度器自己的取消通知。真正阻止它重复提议的是工具描述,其中已写明用户的决定不会被告知。这一发现的代码侧是 #10787;句子在这里修,是因为本 PR 已经在重写同一行物理文本,把两者拆到不同 PR 会造成冲突。命令表里
/goal一行也只列了<condition>和clear,漏掉了edit、pause、resume,而命令解析自 Goal v3 起就接受它们。为什么需要
这四处都会把读者引向错误结论。做 ACP 集成的人会去等一个永远不会到达的流事件。写目标的人会相信一个既非真实上限、也没有解释的字数限制。评估成本的人会以为每轮都有一次 verifier 调用。子代理那条是 #10662 的第一项,已由维护者在该 issue 中验证。
审查者验证计划
如何验证
没有代码改动,无需运行任何命令。每条说法都可以通过阅读对应代码确认。
packages/core/src/config/config.ts中 goal worker 工具的注册在子代理标志为真时提前返回,早于get_goal、update_goal、propose_goal的注册。packages/core/src/goals/goal-tools.ts中PROPOSE_GOAL_OBJECTIVE_MAX_CHARACTERS为 1500;packages/cli/src/ui/commands/goalCommand.ts的命令解析没有任何长度检查。packages/cli/src/acp-integration/acpAgent.ts中的sessionGoalControl,以及 ACP 消息发射器里构造 goal 状态更新的函数,它在session/update上发送_meta.goalState。packages/core/src/goals/goal-runtime.ts的finishTurn只在记录了终止提案时才调用 verifier。goalCommand.ts的解析表接受set、edit、pause、resume、clear。证据(前后对比)
N/A,纯文档改动。
测试环境
运行环境(可选)
N/A,不涉及运行时。对三个改动文件执行了 Prettier 格式化。
风险与范围
关联 Issue
关联:#4228(Phase 1)、#10662、#8732、#10787。