Skip to content

Let agents hand tasks to agents that can read raw secrets; such a task runs fill-only - #53

Merged
danielehrhardt merged 2 commits into
mainfrom
fix/delegate-reveal-agents
Oct 5, 2026
Merged

danielehrhardt merged 2 commits into
mainfrom
fix/delegate-reveal-agents

Conversation

@danielehrhardt

Copy link
Copy Markdown
Contributor

Godmode could not hand a task to an agent with reveal access. The call failed with "Target agent can reveal secrets; only the human can hand it tasks from here.", so every task for such an agent (here: a lead research batch for the Lead Researcher) needed the human.

What you get

  • Any agent that may delegate can hand a task to a reveal-mode agent. Godmode included.
  • That task runs fill-only. Unless the caller reads raw secrets itself (and the target is global or in the caller's workspace), vault_get_login / vault_get_totp are off in the task's chat — for the task and for everything that happens in that chat later. Logins and 2FA codes are still filled into pages.
  • A task that needs a raw secret (an API or CLI that cannot be filled in the browser) does the rest and says so in its summary; that part stays with you.
  • Delegating across workspaces to a reveal-mode agent now works the same way (it was refused before).

Still only for the human

For a reveal-mode agent, a caller that reads no raw secrets still cannot change its settings or instructions, create or change its automations, assign it board tasks or give it a VM. These outlive a single task, so running the task fill-only does not cover them. agent_update for such an agent is refused as before.

How it works

  • agent_delegate no longer calls the reveal refusal. It creates the task's chat with secret_access = 'fill' (new column on conversations, migration 31) when the caller's run could not read raw secrets for that target.
  • The two raw-secret tools are listed and callable only when the agent is in reveal mode and its chat is not fill-only. The runner passes the mark to the prompt, which tells the agent why the tools are off.
  • In a fill-only chat a reveal-mode agent counts as fill-only for the remaining guards — itself included — and for what it delegates on, so the mark follows a chain of hand-overs.
  • A chat whose row is gone counts as fill-only.
  • The rule for agents that control the computer on their own is unchanged.

Migration id 31 leaves a gap on purpose: several branches are open, and a second migration with the same id would be skipped silently.

Risks

  • Memory and files. A handed-over task can write to the target agent's MEMORY.md and repository; a later run of that agent with raw-secret access may act on text planted there. This comes with allowing the hand-over at all — the old refusal was the only thing that prevented it. SECURITY.md says so.
  • Already on main, not changed here: task_update lets a fill-only manager edit the title or description of a board task that is assigned to a reveal-mode agent; vm_assign to a workspace has no reveal check; login allow-lists are not compared when deciding whether a delegated chat keeps raw secrets.

Checked

  • bun test in packages/core: 939 pass, 10 skipped, 0 fail. pnpm typecheck clean.
  • New tests in test/mcp.test.ts: the hand-over from a fill-only delegator and a fill-only manager, the tools and the prompt in that chat (also for a later message in it), the chain, the refusals inside a fill-only chat (own agent included), a chat that is gone, and that the agent still reads raw secrets in a chat of its own.
  • Removing each protection in turn (six of them) makes a test fail.
  • An independent security review found three defects in the first version (a reveal-mode manager could still change itself from a fill-only chat; a missing chat row brought the raw tools back; a doc overclaim). All fixed; a second pass re-tested them as closed.
  • With the real Claude Code CLI in an isolated instance (own data directory): a fill-only, managing Godmode was asked to hand a small lead task to a reveal-mode Lead Researcher. agent_delegate succeeded, the Lead Researcher wrote workspace/leads/smoke.csv and its answer came back; the delegated chat was marked fill-only, the agent reported no raw-secret tools, and no reveal was audited.

Not verified

  • The original lead batches were not re-run: the instance that holds the real Lead Researcher is not on the machine this was developed on.
  • The desktop UI does not show that a chat is fill-only; the agent says so when it matters.

…k runs fill-only

Godmode could not delegate to an agent with reveal access ("Target agent can reveal secrets; only the human can
hand it tasks from here"), so work for such an agent always needed the human. agent_delegate now goes through for
every caller. Unless the caller's run reads raw secrets itself and the target is global or in its workspace, the
task's chat is marked fill-only (conversations.secret_access, migration 31): vault_get_login / vault_get_totp are
off in it for good, the prompt says so, and logins and 2FA codes are still filled into pages. Delegating across
workspaces to a reveal-mode agent works the same way.

In a fill-only chat a reveal-mode agent counts as fill-only for what it hands on or sets up, itself included:
automations, assigning board tasks, agent settings and giving an agent a VM are refused as they are for a
fill-only caller. A chat that is gone counts as fill-only. Those refusals are otherwise unchanged, as is the rule
for agents that control the computer on their own.

The migration id leaves a gap on purpose: several branches are open, and a second migration with the same id
would be skipped without a word.
# Conflicts:
#	docs/ARCHITECTURE.md
#	packages/core/src/db/migrations.ts
#	packages/core/src/mcp/tools.ts
#	packages/core/src/runner/prompt.ts
#	packages/core/src/runner/runner.ts
@danielehrhardt
danielehrhardt merged commit a56e321 into main Oct 5, 2026
7 of 8 checks passed
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