Skip to content

Ground file-edit generations in the actual file contents #22

@CoreyRDean

Description

@CoreyRDean

Observed

When asked to modify a file the user knows exists on disk, i generates a prose-style shell snippet as if it were being pasted into a bash function, rather than reading the file and producing an executable command that edits the real file in place.

Reproduction

i "update my agi alias in my .zshrc file to allow the flag '--profile <profile-name>' where when present it will set CLAUDE_CONFIG_DIR=\$HOME/.claude-<profile-name> before the claude command that it currently runs. If not present it will not set the CLAUDE_CONFIG_DIR variable and will run the command like it currently does."

What i produced (from [p] preview):

interpreter: zsh
| if [[ "$@" == *"--profile"* ]]; then
|   profile_name=$(echo "$@" | grep -oP '(?<=--profile )[^ ]+')
|   export CLAUDE_CONFIG_DIR="/Users/coreyrdean/.claude-$profile_name"
| fi
| exec claude $@

This is not an executable edit. It is a prose transliteration of the user's prompt into zsh-ish code. Running it would not touch ~/.zshrc; it would just define those lines in the current shell for the duration of the call. The user's existing agi alias is never read, never parsed, never replaced.

Expected

Given a request of the form "modify file X to do Y":

  1. i should use read_file on the referenced file (~/.zshrc) to discover the current definition of agi.
  2. Use which / env_get HOME / os_info as needed to resolve the path and the current alias body.
  3. Produce an executable command that rewrites the file in place — likely a sed -i, a small awk script, or a heredoc append — conditioned on the real current state.
  4. The preview should show a command that will actually modify ~/.zshrc, not a snippet in a quote block.

Where this lives

The natural-language path is cmdIntent in internal/cli/intent.go. It runs eng.Run(...) with the user prompt and the standard tool catalog (internal/tools/tools.go:85-90), which already includes read_file, list_dir, grep, find_files, env_get, cwd. The tools exist; the model is just not using them for file-edit requests.

Probable fix surface:

  • The top-level intent system prompt (whatever is fed to engine.Run from cmdIntent — check internal/engine/engine.go) needs an explicit rule: when the user's request references a file path they say exists (~/.zshrc, ~/.config/..., ./foo.conf), the model MUST read_file it before generating an edit command. Generating a script body without first reading the target is a bug.
  • The proposal's risk/runtime slots should probably reflect that an actual in-place file mutation happened, not a no-op script.
  • Consider adding an explicit "file edit" mode or approach where the engine refuses to emit a script that mentions a filesystem path without having read that path.

Related

  • AGENTS.md learned preference: "Every natural-language subcommand (...) must be agentic: run a read-only tool-call loop that discovers binaries on the user's $PATH, lists/reads files, invokes --help/man, uses grep/rg, find/fd, web fetch, and other non-mutating shell calls to gather context iteratively until ready — never describe what would need to be checked instead of checking it." This issue is a direct violation of that rule for file-edit requests.

Acceptance

A command shaped like "modify file X to do Y" with X pointing at a real file should, in the preview pane, show a command whose execution would actually change X on disk, grounded in X's current contents. The model should have called read_file (observable in -v output) before producing that command.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions