Skip to content

[Feat] Let tasks ask the Session owner before running an Ask first tool - #3076

Merged
daniel-lxs merged 2 commits into
developfrom
feat/tool-approvals-task-asks
Sep 21, 2026
Merged

daniel-lxs merged 2 commits into
developfrom
feat/tool-approvals-task-asks

Conversation

@daniel-lxs

Copy link
Copy Markdown
Member

Part of the experimental per-tool approvals (integrationToolApprovals). Until now an Ask first tool was simply unavailable to a task. With this change a task's agent pauses on the call, the owner of the task's Session gets the same approval card a Session shows, and the call runs once they allow it.

How it works

  • Rules. A task run fetches its native ask/deny rules (mcpConnections.getTaskToolApprovals, run token only). They are compiled on the server from the deployment policies, the acting member's personal policies, and the Session's overrides, and written into the task's OpenCode permission config on top of the allow-all defaults.
  • Relay. The worker handles OpenCode's permission.asked (from the main session or a subagent's), reads the paused call's arguments, and records the ask through toolApprovals.request. It polls toolApprovals.status and answers the native ask with once or reject. A pending ask defers the stall watchdog, like a pending question.
  • Decision. A task belongs to one Session, so the approval row lives on that Session (new nullable task_id column), is decided by the Session owner through the existing route, and honors "Allow for this session". The task page shows the Session's card narrowed to that task's asks. A task with no human Session owner (for example one an automation started) cannot be approved, and the ask is rejected with that reason.
  • Enforcement. The agent's config is advisory inside a sandbox, so the integration proxy is what makes the decision real: for a run token, a call to an Ask first tool must claim an approved row for the same task, tool, and arguments. One decision runs one call; other arguments, other tasks, a replay, a rejected or stale decision, and a disabled experiment all claim nothing. Ask first tools are listed for tasks again (they used to be hidden); Reject still hides and refuses. Batches around a gated tool are refused.

Notes

  • Migration 0112 is additive (one nullable column and an index).
  • Session tokens behave as before: a Session's native ask is decided on the control plane before the call reaches the proxy.
  • A session-level "ask" set while a task is already running is enforced by the proxy but has no native rule until the task's next run, so that call is refused rather than asked about.
  • Chat-surface notifications for task asks are not included; the card is on the task page and the Session.

Testing

  • Unit: rule compiler, run-token procedures, proxy blocks with session overrides and the claim, worker relay, harness event routing (including a subagent session), generated config, task page panel.
  • Real database: the claim runs the exact approved call once and nothing else.
  • Live against a local stack with a run token: rules compiled for shared and personal servers; an unapproved call was refused; the card appeared on the task page; after "Allow once" the same call ran, a call with different arguments and a replay were refused, and the row ended consumed. A full sandboxed task run was not exercised locally.

@roomote-community

roomote-community Bot commented Sep 21, 2026 •

Copy link
Copy Markdown
Contributor

No new code issues found. See task

Reviewed 8799850

@daniel-lxs
daniel-lxs merged commit d1fc11c into develop Sep 21, 2026
17 checks passed
@daniel-lxs
daniel-lxs deleted the feat/tool-approvals-task-asks branch September 21, 2026 22:56
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.

1 participant