anthropics / anthropics/claude-code
The agent writes to targets it inferred, without ever saying the target was a guess
- Dominant language
- Python
- Stars
- 145k
- Forks
- 23.1k
- PR merge metrics
- PR metrics pending
Description
## Summary
When a task requires acting on a system the agent cannot fully see — a remote host, a shared
environment, a service directory — the agent often has to *derive* the target: a directory, an
account, a queue, a config file. Today nothing distinguishes a target the user specified from a
target the agent reconstructed by searching. Both are executed the same way, and the permission
prompt (when it fires at all) shows the command, not the provenance of its arguments.
The result is a write into a shared system based on a guess that was never labelled as one.
## What happened
Asked to re-run a job on a shared test environment, the agent had to deposit an input file into a
watched directory. The location was not in the task description, not in the project docs, and not in
the agent's own memory notes. The agent searched the remote filesystem, found a plausible directory,
corroborated it with a timestamp that matched the previous run, and copied the file in — using an
elevated account, because the directory was not writable otherwise.
Everything about that chain was reasonable. The problem is that it was never surfaced. From the
user's side the transcript read as *"dropped the file"* — indistinguishable from following an
instruction. The user only discovered the inference several turns later, after asking *"who told you
to put it there?"*.
The inferred path turned out to be correct. That is not the point: the same chain with a wrong guess
writes into a directory belonging to someone else's pipeline, and nothing in the flow would have
caught it.
## Why the existing safeguards do not cover this
- **Permission prompts are per-tool, not per-argument.** Once a command class is allowed, the
approval says nothing about *where* the command will write, and nothing at all about whether that
destination came from the user or from the agent's own search.
- **Read-only exploration is not gated, and it shouldn't be** — but it is exactly the step that
produces the guess. The transition from "I found a candidate" to "I wrote to it" is invisible.
- **Elevation is treated as a command-shape question.** Escalating to a service account to make a
write succeed reads, in the transcript, like a routine detail rather than a signal that the agent
is operating outside what it was handed.
## Proposal
1. **Track argument provenance for mutating actions.** When a path, host, account, table or queue in
a write/delete/move/publish action was not present in the user's instructions, project
configuration, or an explicitly loaded document, mark it as *derived*.
2. **Surface it once, in one line, before acting.** Not a new permission wall for everything — a
single statement in the agent's own output: *"target not specified; derived from .
Proceeding unless corrected."* Cheap, and it puts the inference where the user can see it at the
moment it still costs nothing to correct.
3. **Require confirmation when derived + irreversible + shared.** A write whose target is derived,
is on a remote or shared system, and cannot be trivially undone is the narrow case that deserves
a real stop. Make it a setting (`confirmDerivedWriteTargets`) so teams that work on disposable
sandboxes can turn it off.
4. **Treat privilege escalation as a provenance signal, not only a permission one.** If a write only
succeeds by switching to another account, that is a strong hint the agent is outside its brief.
## Alternative considered
"Just ask about everything" — rejected. It makes the agent unusable for the long operational tasks
where this matters most. The proposal deliberately keeps the *statement* cheap and reserves the
*block* for the narrow intersection.
## Related gap
The agent reconstructed the target by probing the remote filesystem partly because its own stored
notes on that environment were not in context: only the project-scoped memory directory is surfaced
automatically, while machine and environment facts live in a separate global one that must be read
explicitly. An agent that cannot see its own notes will rediscover them by exploration — which is
both expensive and exactly how a guess gets manufactured. Surfacing an index of *all* memory scopes,
or stating plainly which scopes were not loaded, would remove one of the reasons this pattern
starts.
## Environment
- Claude Code, desktop app
- Task type: multi-step operational work against a remote host over SSH
- Permission mode: auto-approve for the allowed command classes
Contributor guide
No contributing guide indexed for this repository
Research direction
No files or tests are identified. Start by locating the permission-prompt flow and the handling of mutating actions, then trace how target arguments and privilege escalation are represented. Done means derived targets are surfaced before action, and the specified derived, irreversible, shared writes can require confirmation without blocking every operation.
Written by the indexing model from the issue text.
Assessment
- Domain
- authorization, cli, security
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100