Skip to content

docs(goals): sync the Goal docs with the current runtime - #10785

Merged
qqqys merged 3 commits into
QwenLM:mainfrom
qqqys:docs/goal-docs-sync
Sep 3, 2026
Merged

docs(goals): sync the Goal docs with the current runtime#10785
qqqys merged 3 commits into
QwenLM:mainfrom
qqqys:docs/goal-docs-sync

Conversation

@qqqys

@qqqys qqqys commented Sep 2, 2026

Copy link
Copy Markdown
Collaborator

What this PR does

Corrects five statements in the Goal documentation that no longer match what the code does, and completes the /goal row 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 sessionGoalControl extension method, and every status change reaches the client as a session/update notification carrying _meta.goalState rather than as the goal_state stream event the surrounding paragraph describes for --output-format stream-json.

The propose_goal section 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 sees get_goal, update_goal, or propose_goal.

The objective guidance gave a single "roughly under 1,200 characters" figure with no explanation, which reads like an enforced limit. /goal set and /goal edit do 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_goal paragraph 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's execute(), 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 /goal row in the command table also listed only <condition> and clear, omitting edit, pause, and resume, 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.

  • Subagents: the goal worker tool registration in packages/core/src/config/config.ts returns early when the subagent flag is set, before get_goal, update_goal, or propose_goal are registered.
  • Objective cap: PROPOSE_GOAL_OBJECTIVE_MAX_CHARACTERS in packages/core/src/goals/goal-tools.ts is 1500; the command parser in packages/cli/src/ui/commands/goalCommand.ts performs no length check.
  • ACP: sessionGoalControl in packages/cli/src/acp-integration/acpAgent.ts, and the goal state update builder in the ACP message emitter, which sends _meta.goalState on a session/update.
  • Verifier timing: finishTurn in packages/core/src/goals/goal-runtime.ts runs the verifier only when a terminal proposal was recorded.
  • Subcommands: the parse table in goalCommand.ts accepts set, edit, pause, resume, and clear.

Evidence (Before & After)

N/A — documentation only.

Tested on

OS Status
🍏 macOS N/A
🪟 Windows N/A
🐧 Linux

Environment (optional)

N/A — no runtime involved. Prettier formatting was applied to the three touched files.

Risk & Scope

  • Main risk or tradeoff: none to runtime behavior. The only risk is wording drifting again if the runtime changes, which is why each corrected sentence names the mechanism rather than a version.
  • Not validated / out of scope: the remaining items in Deferred review findings from PR #10171 #10662, and the accuracy of Goal documentation outside the five sentences and one table row touched here.
  • Breaking changes / migration notes: none.

Linked Issues

Related: #4228 (Phase 1), #10662, #8732, #10787.

中文说明

这个 PR 做了什么

修正 Goal 文档中五处与代码实现不符的说法,并补全命令表里 /goal 一行。纯文档改动,没有行为变化。

headless 文档说 ACP 仍走旧的 Goal 命令路径。ACP 会话已在 #8732 迁移到 v3 Goal runtime:它通过 sessionGoalControl 扩展方法驱动同一个 runtime,每次状态变化以带 _meta.goalStatesession/update 通知送达客户端,而不是同段落中描述的 --output-format stream-json 下的 goal_state 流事件。

propose_goal 一节说该工具在子代理里会拒绝。实际上没有任何拒绝行为,因为它根本没有注册:goal worker 工具的注册函数在子代理场景下直接返回,子代理从来看不到 get_goalupdate_goalpropose_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,漏掉了 editpauseresume,而命令解析自 Goal v3 起就接受它们。

为什么需要

这四处都会把读者引向错误结论。做 ACP 集成的人会去等一个永远不会到达的流事件。写目标的人会相信一个既非真实上限、也没有解释的字数限制。评估成本的人会以为每轮都有一次 verifier 调用。子代理那条是 #10662 的第一项,已由维护者在该 issue 中验证。

审查者验证计划

如何验证

没有代码改动,无需运行任何命令。每条说法都可以通过阅读对应代码确认。

  • 子代理:packages/core/src/config/config.ts 中 goal worker 工具的注册在子代理标志为真时提前返回,早于 get_goalupdate_goalpropose_goal 的注册。
  • 目标上限:packages/core/src/goals/goal-tools.tsPROPOSE_GOAL_OBJECTIVE_MAX_CHARACTERS 为 1500;packages/cli/src/ui/commands/goalCommand.ts 的命令解析没有任何长度检查。
  • ACP:packages/cli/src/acp-integration/acpAgent.ts 中的 sessionGoalControl,以及 ACP 消息发射器里构造 goal 状态更新的函数,它在 session/update 上发送 _meta.goalState
  • verifier 时机:packages/core/src/goals/goal-runtime.tsfinishTurn 只在记录了终止提案时才调用 verifier。
  • 子命令:goalCommand.ts 的解析表接受 seteditpauseresumeclear

证据(前后对比)

N/A,纯文档改动。

测试环境

操作系统 状态
🍏 macOS N/A
🪟 Windows N/A
🐧 Linux

运行环境(可选)

N/A,不涉及运行时。对三个改动文件执行了 Prettier 格式化。

风险与范围

  • 主要风险或取舍:对运行时行为没有风险。唯一风险是 runtime 变化后措辞再次过期,因此每处修正都描述机制而不是版本号。
  • 未验证 / 不在范围内:Deferred review findings from PR #10171 #10662 的其余条目,以及本次改动的五句话和一行表格之外的 Goal 文档准确性。
  • 破坏性变更 / 迁移说明:无。

关联 Issue

关联:#4228(Phase 1)、#10662#8732#10787

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

qwen-code-ci-bot commented Sep 2, 2026

Copy link
Copy Markdown
Collaborator

Qwen Triage finishedview run. See the stage comments in this thread for the result.

Qwen Triage 已完成 —— 查看运行。结果见本线程中的各阶段评论。

@qwen-code-ci-bot qwen-code-ci-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 does and ## Why it's needed — the prose you wrote covers both, it just needs to live under the headings
  • The ## Reviewer Test Plan subsections: ### How to verify (your grep pointers fit perfectly here), ### Evidence (Before & After) (N/A is fine for a docs PR), and the ### Tested on table
  • ## Risk & Scope
  • ## Linked Issues — your Related: #4228 / #10662 references 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

@qwen-code-ci-bot

qwen-code-ci-bot commented Sep 2, 2026

Copy link
Copy Markdown
Collaborator

📄 Docs-only change — the automatic review ran at --effort medium (verified findings, no reverse audit; medium posts no inline comments). Outcome:

Review complete: pr-10785 — Comment, not posted (0 Critical, 2 Suggestion)

Reviewed head: 7de45f0d4682ee69d35c6490896f20e4a7161821. Full report in the workflow run. For a full high-effort review with inline comments, comment @qwen-code /review.

中文说明

📄 纯文档变更 —— 自动评审以 --effort medium 运行(发现已验证、无反向审计;medium 不发布行内评论),结果见上方引用行。评审的 head:7de45f0d4682ee69d35c6490896f20e4a7161821。完整报告见 workflow 运行;如需带行内评论的完整高强度(high-effort)评审,请评论 @qwen-code /review

…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 qwen-code-dev-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 /goal subcommand list in commands.md matches the parser surface, the propose_goal section now reflects the actual decline contract (model sees only "not approved" and must not re-propose — same wording as PROPOSE_GOAL_NOT_APPROVED_MESSAGE) and the session_permission_vote-era registration behavior (subagents never offered), and the ACP note names sessionGoalControl / _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 yiliang114 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 via goalState in session updates — the legacy-path note was stale.
  • registerGoalWorkerTools returns early on forSubAgent (config.ts), so subagents are never offered propose_goal — "never offered" is the accurate wording, not "refuses".
  • The /goal subcommand list matches goalCommand (set/edit/pause/resume/clear).
  • No length cap on /goal set/edit objectives; propose_goal is capped at PROPOSE_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.

@qqqys
qqqys added this pull request to the merge queue Sep 3, 2026
Merged via the queue into QwenLM:main with commit b549731 Sep 3, 2026
42 of 43 checks passed
@qwen-code-ci-bot

Copy link
Copy Markdown
Collaborator

Released in v0.23.0.

@chiga0

chiga0 commented Sep 3, 2026

Copy link
Copy Markdown
Collaborator

Post-merge review of head 56ae65c6 (merged during review; no approval event). Docs-only Scan-tier pass: all six corrected claims verified against the code at this head.

Verified

  • /goal command surface: the parser accepts set/edit/pause/resume/clear and a bare objective (packages/cli/src/ui/commands/goalCommand.ts:55-71), matching the new commands.md row.
  • Verifier cadence: verificationAttempt is created only when a proposal is readyForVerification (packages/core/src/goals/goal-runtime.ts), i.e. the verifier judges terminal proposals, not every turn — the corrected intro is accurate.
  • Objective length: no length check anywhere in the /goal set/edit path; the only cap in the system is PROPOSE_GOAL_OBJECTIVE_MAX_CHARACTERS = 1500 on propose_goal (goal-tools.ts:606).
  • Subagents: registerGoalWorkerTools returns early for subagents (packages/core/src/config/config.ts), so none of get_goal/update_goal/propose_goal are ever registered there — "subagents are never offered it" is the accurate wording.
  • Decline contract: the scheduler settles a declined confirmation as cancelled without entering execute() (coreToolScheduler.ts Cancel branch), so the model sees the scheduler's cancellation notice and the don't-re-propose instruction comes from the tool description — matches the corrected paragraph.
  • ACP: sessionGoalControl extension method exists (acpAgent.ts) and status changes ride session/update with _meta.goalState (MessageEmitter.ts).

One follow-up worth tracking (minor, non-blocking). The propose_goal approval-dialog headline still carries the exact statement this PR removes from the docs: proposalPromptHeadline (packages/core/src/goals/goal-tools.ts:731,733 at this head) says "Approving sets it like /goal set: after each turn an independent verifier checks the transcript...". Docs and dialog matched before this PR (both stale); now they contradict. Same shape as the decline-message cleanup that went to #10787 — a one-line code follow-up would close it.

Reviewed with AI assistance.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants