Skip to content

feat(helper): update the current session goal through Cindy tools - #8362

Open
randomradio wants to merge 3 commits into
makecindy:mainfrom
randomradio:feat/session-goal-api
Open

randomradio wants to merge 3 commits into
makecindy:mainfrom
randomradio:feat/session-goal-api

Conversation

@randomradio

@randomradio randomradio commented Nov 1, 2026 •

Copy link
Copy Markdown

这次改了什么

摘要

Agents can read and replace their current session’s existing Goal Mode objective through cindy_helper.

  • get_goal {} returns the current goal, limits and counters, or goal: null. Reading does not resume execution.
  • update_goal { objective } reuses the goal editor’s controller, persistence, edit marker and status broadcasts.
  • The current turn continues. Later goal turns use the replacement objective. Limits and counters remain unchanged.
  • Changing a paused, blocked or usage-limited objective can resume execution, subject to existing budget and usage checks.
  • Autonomous resume effects require the existing owner confirmation. The confirmation binds the goal’s objective and status.
  • Delayed writes, resumes and the first vendor dispatch recheck admission. Coordinator-tracked input completion preserves an admitted resume. Replacement input, Stop and revocation invalidate it.

变更类型

  • feat 新功能
  • fix 缺陷修复
  • refactor / perf 重构或性能优化
  • docs / test / chore 文档、测试或工程维护
  • 其他:

范围

  • 关联 Issue / 需求:Expose the current session’s goal prompt for in-session edits.
  • 本 PR 包含:Tool discovery, host callbacks, current account/session checks, mutation authorization, resume confirmation and regression coverage.
  • 明确不包含:Goal creation, foreign session/device targets, system prompt changes, database migrations or native changes.
  • 用户可见变化:Agents can inspect and edit an existing goal during execution. Owner and entrusted requests retain normal permission handling.
  • 是否存在 breaking change:无。

UI 变化

不涉及。The API reuses existing status broadcasts, editor behavior and permission cards.

  • 引用的设计规范:不涉及。

怎么验证的

自动验证

Desktop: 1,162 tests passed across 10 files. The MCP package’s 177 tests passed during the API implementation.

# 9 files, 538 tests passed
pnpm --filter desktop exec vitest run src/main/goal-host/__tests__/controller.test.ts src/main/goal-host/__tests__/sessionRestore.test.ts src/main/goal-host/__tests__/index.test.ts src/main/maker-ipc/__tests__/taskActionAuthorization.test.ts src/main/maker-host/__tests__/mcpToolApprovalPolicy.test.ts src/main/mcp-integrations/__tests__/collabSendOutcome.test.ts src/main/mcp-integrations/__tests__/pluginTaskHelperScope.test.ts src/main/mcp-integrations/__tests__/codexEnvironment.test.ts src/main/mcp-integrations/__tests__/botTaskCreationResponsibility.test.ts --maxWorkers=2 --reporter=dot

# 624 tests passed
pnpm --filter desktop exec vitest run src/main/maker-ipc/__tests__/agent-input-coordinator.test.ts --maxWorkers=1 --reporter=dot

# 17 files, 177 tests passed during API implementation
pnpm --filter @cindy/mcps exec vitest related src/lizi_xdtHelperMcpServer.ts src/xdt-helper/goal.ts src/xdt-helper/index.ts src/xdt-helper/capabilities.ts --run --maxWorkers=4 --reporter=default

# Passed
pnpm --filter desktop run --if-present typecheck
pnpm --filter @cindy/mcps run --if-present typecheck
pnpm --filter @cindy/mcps exec tsc --noEmit
pnpm check:dev-docs
pnpm check:test-hygiene
git diff --check

The MCP package has no typecheck script; tsc --noEmit supplies its type check.

测试价值

All modified test files use the unit tier with injected memory dependencies or in-memory MCP transport. Each file also passed alone with one worker. Times include command startup.

File Real entry and observable result Rule and previous coverage gap Minimum failure input Standalone result
goal-host/__tests__/controller.test.ts createSessionGoalCallbacks and the controller persist edits, broadcast state and dispatch the new objective. agent-user-parity.md, teammate-authority.md: earlier tests omitted MCP lifecycle revocation and confirmed goal snapshots. Revoke during a storage/restore/dispatch wait; replace an admitted goal; edit a paused goal before deferred resume. An unchanged absent goal still returns GOAL_NOT_FOUND. 251 passed; 8.92 s.
maker-ipc/__tests__/taskActionAuthorization.test.ts Real host admission, callback and controller require resume confirmation and preserve the admitted resume after completion. teammate-authority.md, reviews r4436235377 and r4436295232: previous cases lacked goal risk facts and the completion transition. Decline a paused-goal edit; change the captured objective/status; clear the originating input; replace input or revoke permissions before resume. 164 passed; 3.89 s.
maker-ipc/__tests__/agent-input-coordinator.test.ts Real coordinator completion proof accepts normal completion and rejects replacement or Stop. teammate-authority.md, r4436295232: clearing active input previously lost the distinction between completion and supersession. Finish the original input, then finish another; queue and cancel replacement input; Stop after completion. 624 passed; 13.05 s. Existing suite collection took 4.05 s and execution took 8.35 s. The three new cases use the existing memory harness.
maker-host/__tests__/mcpToolApprovalPolicy.test.ts Production policy requires ordinary review for edits while keeping reads quiet. agent-user-parity.md: the existing mutation matrix omitted the new tool. Direct, progressive, unnamed outer and serialized update_goal calls. 46 passed; 0.56 s.
mcp-integrations/__tests__/collabSendOutcome.test.ts Provider collaboration outcomes still pass. Fixture maintenance: mock the goal-host singleton imported by providers. No new scenario. Load providers through the existing Electron-free fixture. 16 passed; 8.38 s. Collection accounts for 7.70 s.
lizi-mcps/src/__tests__/lizi_xdtHelperMcpServer.test.ts Real list_tools / call_tool messages expose tools, bind the live caller and enforce arguments/authorization. agent-user-parity.md: no goal tool protocol coverage existed. Replace the bridge caller, deny mutation, or supply a blank objective, foreign target, limit field or absent caller. Covers Claude, Codex and Pi contexts. 42 passed; 1.17 s.

Regression cases reproduced the authorization and confirmation failures before their fixes. Both owner and autonomous deferred resumes also failed under the old input-bound guard and passed with the completion guard.

手工验证

Reviewed the complete diff. Independent review checked confirmation binding, delayed state checks, completion and superseding input.

未执行的验证

No live Desktop, Windows or Mobile app verification. The full repository suite was not run. CI remains required.

风险

风险分类

  • 无已知风险
  • SQLite / migration
  • system prompt
  • 协议兼容
  • 权限 / 安全 / 用户数据
  • 存量插件兼容(批准状态 / 指纹 / manifest 校验 / 安装布局 / 包格式)
  • 原生层 / fingerprint / OTA
  • 跨平台差异
  • 其他:Editing a paused goal can resume execution, matching the existing editor.

影响与回滚

  • 影响范围:Only the runtime caller’s existing goal on its Cindy host. Account, session and controller replacement invalidate access.
  • Autonomous resume confirmation binds the goal’s objective and status through controller waits and deferred resume. Active, unchanged, owner and entrusted edits retain normal permission handling.
  • Authorization is checked before submitting each side effect. A database write already submitted under valid admission may still finish after revocation. Its edit marker completes, while later resume or dispatch is blocked. PRECONDITION_FAILED does not guarantee unchanged state; callers must use get_goal before retrying.
  • The resume guard ends at first vendor dispatch. Later ordinary goal continuations use their existing lifecycle and permissions.
  • 回滚 / 降级方式:Revert the PR commits to remove the tools and associated authorization changes. Existing goal data and UI editing remain compatible; no migration is required.

提交前检查

  • 已 review 完整 diff
  • 每个 commit 都带 DCO 签名(git commit -s)
  • UI 改动已在「UI 变化」注明引用的设计规范章节(不涉及 UI)
  • 未提交凭证、令牌或授权文件
  • 已核对受影响的文档,行为变化涉及的旧结论已同步修订
  • 已确认测试结果或说明未执行原因

Signed-off-by: Ian Chenyang Zhao <chzhao8904@gmail.com>
@randomradio
randomradio requested a review from a team as a code owner November 1, 2026 15:12
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 1, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-01T16:19:59.739752Z b9eef8d New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@greptile-apps

greptile-apps Bot commented Nov 1, 2026 •

Copy link
Copy Markdown

RetriggerView in GreptileConfidence Score: 3/5

[Medium impact] The PR adds goal access for agents, limited to the current task on its Cindy host.

建议修复目标写入的权限复核窗口后再合并。

Findings

  1. P1 Security 权限收紧后仍修改目标 ▶
Fix with agent prompt
### Issue 1
apps/desktop/src/main/mcp-integrations/sessionGoal.ts:29-34
`update_goal` 只在进入 `updateGoal` 前调用一次 `assertTaskActionCurrent()`。伙伴自动轮获准后,控制器还会等待已有写入并读取目标。如果用户此时开启 Plan 模式,旧许可已经失效,但控制器仍会保存新目标。返回后的检查只核对账号、实例和控制器,因此还可能报告成功。

请把本次调用的权限检查传到控制器,在等待结束后、提交目标及恢复执行前重新检查。

**How this was verified:** 获准调用的 Plan 代次会在切换开始时失效,但 `updateGoal` 等待后直接写入,未再次检查该许可。

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Summary

本 PR 为当前任务新增目标读取与修改工具。

  • Agents can read and replace the goal for their current task.

Diagram

sequenceDiagram
  participant A as Agent
  participant T as cindy_helper
  participant H as Host
  participant G as GoalController
  A->>T: call_tool
  T->>H: 检查当前调用权限
  H->>G: updateGoal
  G->>G: 等待已有写入并读取目标
  Note over H,G: 此时用户可能开启 Plan 模式
  G->>G: 保存新目标
  G-->>H: 返回目标
  H-->>A: 返回结果
Loading

Reviews (1) · Last reviewed commit: "feat(helper): update the current session..." · Reviewed by Greptile

Comment on lines +29 to +34
if (objective !== undefined) await assertTaskActionCurrent();
assertSessionCurrent();
if (deps.getController() !== controller) throw new GoalControllerDisposedError();
const goal = objective === undefined
? await controller.getStatus(sessionId)
: await controller.updateGoal(sessionId, { objective });

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 security 权限收紧后仍修改目标

update_goal 只在进入 updateGoal 前调用一次 assertTaskActionCurrent()。伙伴自动轮获准后,控制器还会等待已有写入并读取目标。如果用户此时开启 Plan 模式,旧许可已经失效,但控制器仍会保存新目标。返回后的检查只核对账号、实例和控制器,因此还可能报告成功。

请把本次调用的权限检查传到控制器,在等待结束后、提交目标及恢复执行前重新检查。

How this was verified: 获准调用的 Plan 代次会在切换开始时失效,但 updateGoal 等待后直接写入,未再次检查该许可。

Knowledge Base Used: Agent tool and computer integrations

Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/desktop/src/main/mcp-integrations/sessionGoal.ts
Line: 29-34

Comment:
**权限收紧后仍修改目标**

`update_goal` 只在进入 `updateGoal` 前调用一次 `assertTaskActionCurrent()`。伙伴自动轮获准后,控制器还会等待已有写入并读取目标。如果用户此时开启 Plan 模式,旧许可已经失效,但控制器仍会保存新目标。返回后的检查只核对账号、实例和控制器,因此还可能报告成功。

请把本次调用的权限检查传到控制器,在等待结束后、提交目标及恢复执行前重新检查。

**How this was verified:** 获准调用的 Plan 代次会在切换开始时失效,但 `updateGoal` 等待后直接写入,未再次检查该许可。

**Knowledge Base Used:** [Agent tool and computer integrations](https://app.greptile.com/-/switch-tenant?tenant=xindong&next=%2Fcustom-context%2Fknowledge-base%2Fmakecindy%2Fcindy%2F-%2Fdocs%2Fagent-tool-and-computer-integrations.md)

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: cae2cff3be

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

if (deps.getController() !== controller) throw new GoalControllerDisposedError();
const goal = objective === undefined
? await controller.getStatus(sessionId)
: await controller.updateGoal(sessionId, { objective });

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Recheck action authorization before committing a Goal edit

If a Bot or automatically triggered call loses its permission, Plan, or input generation while GoalController.updateGoal() awaits lifecycle persistence or storage.get(), it still writes the new objective and reports success. The action guard runs only before entering the controller; the subsequent checks cover account/session identity, not action authorization. An in-memory reproduction committed the edit despite an expired TaskAction scope. This contradicts the post-admission revocation contract in agent-user-parity.md; pass the captured action guard into the controller and recheck it at the mutation/resume boundaries.

AGENTS.md reference: AGENTS.md:L55-L58

Useful? React with 👍 / 👎.

'steer_session',
'stop_session_turn',
'set_session_runtime',
'update_goal',

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Require confirmation before autonomously resuming a Goal

For an autonomous companion turn with an existing paused Goal, changing the objective queues a Goal resume, but registering update_goal only in TASK_ACTION_TOOLS leaves taskActionRisk() returning undefined. Consequently, a Full Access autonomous turn can restart the user's paused execution without owner confirmation. An in-memory reproduction resumed and dispatched the Goal with zero confirmations, whereas the equivalent message_session_task(mode='resume') requested confirmation and was denied. teammate-authority.md requires that additional confirmation for resuming paused execution; capture the current Goal state and route this effect through the existing resume risk gate before editing.

AGENTS.md reference: AGENTS.md:L73-L74

Useful? React with 👍 / 👎.

Signed-off-by: Ian Chenyang Zhao <chzhao8904@gmail.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 24d4a03376

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +2279 to +2281
const assertCurrent = this.deferredManualResumeContexts.get(sessionId)?.assertCurrent;
void this.resumeGoal(sessionId, { assertCurrent }).catch((error) => {
this.cancelDeferredManualResume(sessionId, { restoreUsageResume: true });

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Preserve deferred Goal resume across normal turn completion

When a Bot—including an owner-requested turn—changes a paused or blocked Goal from its currently running session, the resume is deferred. The saved assertCurrent checks the live task-action input key, which getTaskActionInputState() derives from { input, executing }; normal turn completion clears that input in agent-input-coordinator.ts:4280. Consequently, this retry throws TASK_ACTION_AUTHORIZATION_EXPIRED and cancels the resume even when the account and permissions are unchanged and no replacement input arrived. An in-memory run of the real authorizer, callback and controller returned ok: true but left the edited Goal paused with zero sends, unlike the editor path. Preserve the admitted resume through expected completion of its originating turn while retaining checks for actual revocation or superseding input.

AGENTS.md reference: AGENTS.md:L57-L58

Useful? React with 👍 / 👎.

@MagicLizi

Copy link
Copy Markdown
Contributor

本 PR 命中维护者确认门(product:feat 类型;rules:改到审查判据 docs/product-rules/agent-user-parity.md;arch:核心路径 450 行 ≥ 150),自动审查流程不会继续审查或合并。

本次改动为 cindy_helper 新增 get_goal / update_goal:Agent 可读取并改写当前任务的目标模式提示词(复用 GoalController 编辑、持久记录与状态广播;修改暂停/受阻目标会恢复执行;不打断当前轮、不新建目标、不可指定其他任务或电脑),并配套任务操作授权、审批策略与回归测试。逐文件语义核对不属于 bugfix/已有功能补充/纯技术改动/机械编辑的豁免范围,需要维护者确认。

请维护者直接在本 PR 上 Approve 确认(需要修改则 Request Changes)。讨论 issue:#8365

@MagicLizi MagicLizi added awaiting-discussion 等待维护者讨论(review-pr) touches:core 改动碰到架构核心路径(review-pr 自动维护,仅展示) touches:product-ui 改动碰到产品 / UI 面(review-pr 自动维护,仅展示) touches:rules 改动碰到规则 / 规范文档(review-pr 自动维护,仅展示) labels Nov 1, 2026
…ions

Signed-off-by: Ian Chenyang Zhao <chzhao8904@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

awaiting-discussion 等待维护者讨论(review-pr) touches:core 改动碰到架构核心路径(review-pr 自动维护,仅展示) touches:product-ui 改动碰到产品 / UI 面(review-pr 自动维护,仅展示) touches:rules 改动碰到规则 / 规范文档(review-pr 自动维护,仅展示)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants