Skip to content

aid: start every agent in full auto, not just claude - #585

Merged
blooop merged 2 commits into
mainfrom
fix/584-full-auto-for-every-agent
Sep 7, 2026
Merged

aid: start every agent in full auto, not just claude#585
blooop merged 2 commits into
mainfrom
fix/584-full-auto-for-every-agent

Conversation

@blooop

@blooop blooop commented Sep 7, 2026

Copy link
Copy Markdown
Owner

Closes #584.

aid --claude has run with --dangerously-skip-permissions since the Python build.
aid --codex and aid --gemini ran their CLIs bare, so codex stopped at its first
approval prompt and gemini at its first tool call. An aid owner/repo fix the bug
on either of them opened a workspace, printed a question, and waited for somebody
who had already walked away.

The reason for claude's flag was never claude-specific: the agent is already inside
a disposable container holding only this repo, so the per-tool prompts buy nothing.
That is true of every row in the table, so every row now carries a flag.

Agent What aid runs
claude claude --dangerously-skip-permissions, with IS_SANDBOX=1 beside it
codex codex --dangerously-bypass-approvals-and-sandbox
gemini gemini --yolo

codex gets the bypass and not --full-auto

This is the one decision in the change worth arguing with. --full-auto reads like
the answer: it approves every action. It also keeps codex's own sandbox, which is
workspace-write with the network off, so gh, cargo fetch and pip install would
fail inside a container that has a network and a checkout the agent is meant to be
able to push from. The container is already the sandbox; nesting a second one inside
it subtracts exactly the capabilities dl went to the trouble of provisioning.

Guards

Two, and they promise different things.

every_agent_starts_in_full_auto holds the rule against the table rather than
against one row: it asserts its expected list against AGENTS.len(), so an agent
added later without a flag fails there instead of in somebody's unattended run. The
spellings are named rather than pattern-matched, because --full-auto matches any
pattern loose enough to cover three CLIs.

The full-auto table added to docs/cli.md is a second hand-maintained copy of a
fact rewrite.rs owns, so it gets the diff test this repository requires beside
one. the_full_auto_section_names_the_flags_each_agent_is_actually_started_with
parses the rows under the heading and diffs each against the command the devpod shim
actually receives, which is a launch rather than another copy of the list. Verified
to bite: rewriting the codex row to --full-auto fails it with the page and the
launch printed side by side.

What is unchanged

A command you typed yourself. dl <ws> -- codex runs codex, exactly as written,
with no flags added and no variables set. The README paragraph that said the trade
applied "to aid starting claude and nothing else" was the sentence this change
falsifies, and it is rewritten rather than left standing.

Checks

cargo test --workspace (32 suites), cargo clippy --locked --all-targets -D warnings, cargo fmt --check and pixi run test (717) all pass in the container.

🤖 Generated with Claude Code

Summary by Sourcery

Start every agent launched by aid in its CLI-specific full-auto mode to support unattended workspace runs.

Bug Fixes:

  • Start Codex and Gemini agents in full-auto mode so unattended aid runs no longer stop at approval or tool prompts.

Enhancements:

  • Preserve manually supplied dl commands unchanged while applying agent-specific full-auto flags only to agents launched by aid.
  • Document the full-auto behavior, agent-specific flags, Codex sandbox rationale, and associated safety trade-offs.

Documentation:

  • Update the README, CLI documentation, and changelog to describe full-auto startup for every supported agent.

Tests:

  • Add guards verifying every configured agent has the expected full-auto flag and that the documented flags match the commands launched by aid.

`aid --claude` has run with `--dangerously-skip-permissions` since the Python
build. `aid --codex` and `aid --gemini` ran their CLIs bare, so codex stopped at
its first approval prompt and gemini at its first tool call, and an
`aid owner/repo fix the bug` on either opened a workspace, printed a question and
waited for somebody who had already walked away.

The reason for claude's flag was never claude-specific. It is that the agent is
already inside a disposable container holding only this repo, so the per-tool
prompts buy nothing, and that is true of every row in the table. So the table now
carries a full-auto flag per agent: `--dangerously-skip-permissions` for claude,
`--dangerously-bypass-approvals-and-sandbox` for codex, `--yolo` for gemini.

**codex gets the bypass and not `--full-auto`.** That is the trap here, because
`--full-auto` reads like the answer: it approves every action, and it keeps codex's
own sandbox, which is workspace-write with the network off. `gh`, `cargo fetch` and
`pip install` would fail inside a container that has a network and a checkout the
agent is meant to be able to push from. The container is already the sandbox, so a
second one nested inside it removes exactly the capabilities `dl` provisioned.

Held as a rule, not as three assertions. `every_agent_starts_in_full_auto` reads
`AGENTS` and asserts its own length against the list of spellings it expects, so an
agent added without a flag fails there rather than in somebody's unattended run.
The spellings are named rather than pattern-matched, because `--full-auto` matches
any pattern loose enough to cover three CLIs and picking it would be a silent
regression.

The full-auto table added to docs/cli.md is a second hand-maintained copy of that
fact, so it gets the guard this repository requires beside one:
`the_full_auto_section_names_the_flags_each_agent_is_actually_started_with` parses
the table under the heading and diffs each row against the command the devpod shim
receives, which is a launch rather than another copy of the list. Verified to bite
by rewriting the codex row to `--full-auto` and watching it fail.

The README paragraph that said the trade applied "to `aid` starting `claude` and
nothing else" is now wrong and says so.

Closes #584
@sourcery-ai

sourcery-ai Bot commented Sep 7, 2026

Copy link
Copy Markdown

Reviewer's Guide

aid now launches Claude, Codex, and Gemini in CLI-specific full-auto modes so unattended runs do not stop for approval prompts, while manually supplied dl commands remain unchanged. Tests enforce coverage for every registered agent and keep the documentation table synchronized with actual launch commands.

Sequence diagram for full-auto aid agent launch

sequenceDiagram
    participant User
    participant Aid
    participant Devpod
    participant Agent

    User->>Aid: aid --agent owner/repo prompt
    Aid->>Aid: build_agent_command()
    Aid->>Devpod: launch workspace with agent command
    Devpod->>Agent: start CLI in full-auto mode
    Note over Agent: claude --dangerously-skip-permissions<br/>codex --dangerously-bypass-approvals-and-sandbox<br/>gemini --yolo
    Agent-->>User: run unattended without approval prompts
Loading

Flow diagram for managed versus manual agent commands

flowchart LR
    A[aid agent launch] --> B[CLI-specific full-auto flag]
    B --> C[Disposable container workspace]
    C --> D[Unattended agent run]
    E[dl workspace -- command] --> F[Run command exactly as typed]
    F --> G[No flags or environment changes]
Loading

File-Level Changes

Change Details Files
Start all agents launched by aid with their CLI-specific unattended-mode flag.
  • Add Codex's --dangerously-bypass-approvals-and-sandbox.
  • Add Gemini's --yolo, preserving its prompt behavior.
  • Keep Claude's existing permission bypass and IS_SANDBOX=1 handling unchanged.
rust/aid/src/rewrite.rs
Add regression coverage that enforces full-auto behavior and verifies launch commands.
  • Assert every registered agent has its expected named flag, including promptless launches.
  • Update unit and integration expectations for Codex and Gemini commands.
  • Verify the documentation table matches the commands received by the devpod shim.
rust/aid/src/rewrite.rs
rust/aid/tests/rewrite.rs
Document the new full-auto policy, Codex flag choice, and unchanged manual-command behavior.
  • Add the per-agent launch table and explain why Codex uses the bypass rather than --full-auto.
  • Update README wording to cover every agent and clarify that direct dl commands are untouched.
  • Record the change in the unreleased changelog.
docs/cli.md
README.md
CHANGELOG.md

Assessment against linked issues

Issue Objective Addressed Explanation
#584 Start every agent launched by aid in its CLI-specific full-auto mode: keep Claude's existing permission bypass, add Codex's --dangerously-bypass-approvals-and-sandbox, and add Gemini's --yolo.
#584 Preserve manually specified dl commands without injecting agent-specific flags or environment variables.
#584 Document the full-auto behavior and add safeguards ensuring every configured agent has the appropriate flag and the CLI documentation matches the actual launch commands.

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai 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.

Hey - I've found 1 issue

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="rust/aid/tests/rewrite.rs" line_range="586-590" />
<code_context>
     fn gemini_gets_its_interactive_flag_only_beside_a_prompt() {
         assert_eq!(
             build_agent_command("gemini", "hi", None).as_deref(),
-            Some("gemini --prompt-interactive hi")
</code_context>
<issue_to_address>
**issue (testing):** The documentation guard checks only that the parsed table has three rows and that each parsed agent name is recognized; it does not require the three names to be distinct or to cover `claude`, `codex`, and `gemini`. Replacing one row with a duplicate recognized agent while omitting another therefore makes the test pass despite the table being incomplete.

**Triggers:** When the hand-maintained table is edited with a duplicated agent row and a different agent is omitted.

**Suggested fix:** Collect the parsed agent names into a set and assert equality with the expected agent set, while also rejecting duplicate rows.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨

Comment thread rust/aid/tests/rewrite.rs Outdated
@codecov

codecov Bot commented Sep 7, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 94.86%. Comparing base (4af27b3) to head (659428b).

Additional details and impacted files
Flag Coverage Δ
python 42.98% <ø> (ø)
rust 95.13% <100.00%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Components Coverage Δ
shipped code (rust) 95.13% <100.00%> (+<0.01%) ⬆️
harness and tooling (python) 42.98% <ø> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Four findings from Sourcery and a fresh-context review of 6b18b3e, none in the
behaviour and all in what was written to hold it.

**Both guards counted rows where they had to compare names.**
`every_agent_starts_in_full_auto` asserted `expected.len()` against `AGENTS.len()`,
which never checks that `expected` *covers* the table: dropping claude's flag and
duplicating codex's row is still three rows beside a three-row table, and the review
demonstrated it passing with claude launching bare. The docs guard had the same
shape, and Sourcery broke it on sight. Both now diff the sorted set of names, which
subsumes the count.

**Both compared flags by substring.** Every truncation of a flag is a substring of
it and so is every flag that merely starts with one, so a docs table reflowed down to
`--d` passed, and `command: &["gemini", "--yolo-dry-run"]` passed a
`contains("--yolo")` while asking gemini for the opposite of full auto. Both now
compare whole argv words. This is the trap
`the_force_placement_section_quotes_the_refusals_it_says_it_does` already recorded
for the same reason, and the comments now cite each other.

`full_auto_rows`'s `["claude", "codex", "gemini"]` allow-list was itself a fourth
copy of the agent list, and worse than a copy: it *skipped* any row naming a fourth
agent, so that row's flag went unchecked. Rows are now recognised by shape, a single
backticked word in the first cell, and an unknown name reaches the caller and fails
at the launch. The backticks are what separate a row from the `| --- |` separator,
whose cells begin `--` and parsed as an agent named `---`.

**`--full-auto` does not approve every action, and saying it did conceded the
argument.** It is an approval policy plus a sandbox, not an absence of approvals, so
it still escalates to a person (openai/codex#6522, openai/codex#4847). That is the
*strongest* reason not to use it here, because stopping to ask is the whole of
what #584 is about, and the prose had thrown it away and kept only the sandbox
half. Corrected in the table's doc comment, docs/cli.md, the changelog and the
README. Only `--dangerously-bypass-approvals-and-sandbox` sets the policy to never
ask.

**The README was a third hand-maintained copy of the flags with no guard on it.**
The review made all three wrong and both suites stayed green, which is fair: the PR
invoked the standing rule to justify a guard for docs/cli.md and then left the same
fact next door unguarded. Rather than add a fourth guard, the README now states the
rule and links the docs table for the spellings, keeping claude's flag because the
`IS_SANDBOX=1` paragraph is about it. That is what "README orients, docs explains"
asks for anyway, and the new anchor is checked by test_docs_links.

Also: the docs table was headed "What `aid` runs" while showing less than a launch
does, since a default claude line also carries
`CLAUDE_CODE_DISABLE_TERMINAL_TITLE=1` and `--remote-control=<workspace>`. It is
headed "Full-auto flag" now and says what it omits. docs/cli.md's opening paragraph
enumerates the page's sections and had not been extended for the new one.

Not verifiable here and stated rather than claimed: neither codex nor gemini is
installed in this container, so `gemini --yolo --prompt-interactive <prompt>` is
checked as a string the fake devpod records and not as a process that ran.
@blooop

blooop commented Sep 7, 2026

Copy link
Copy Markdown
Owner Author

Review round on 6b18b3e, addressed in 659428b. Four findings, none in the
behaviour and all in what was written to hold it. Sourcery found the first; a
fresh-context review by an agent that did not write the change found the rest.

Both guards counted rows where they had to compare names. expected.len()
against AGENTS.len() never checks that expected covers the table: dropping
claude's flag and duplicating codex's row is three rows beside a three-row table,
and it was demonstrated passing with claude launching bare. Sourcery found the
identical shape in the docs guard. Both now diff the sorted set of names, which
subsumes the count.

Both compared flags by substring. Every truncation of a flag is a substring of
it, and so is every flag that merely starts with one: a docs table reflowed to --d
passed, and command: &["gemini", "--yolo-dry-run"] passed a contains("--yolo")
while asking gemini for the opposite of full auto. Both compare whole argv words
now. Same trap the_force_placement_section_quotes_the_refusals_it_says_it_does
already recorded, and the comments now cite each other.

full_auto_rows's allow-list was itself a fourth copy of the agent list, and worse
than a copy: it skipped a row naming an unknown agent, so that row went unchecked.
Rows are recognised by shape now, and an unknown name fails at the launch.

--full-auto does not approve every action, and saying it did conceded the
argument.
It is an approval policy plus a sandbox, not an absence of approvals, so
it still escalates to a person (openai/codex#6522 — Incorrect full-auto description in codex --help,
openai/codex#4847 — full-auto doesn't activate on-failure approval policy).
That is the strongest reason not to use it here, since stopping to ask is the whole
of #584, and the prose had thrown
it away and kept only the sandbox half. Corrected in four places.

The README was a third hand-maintained copy of the flags with no guard. All three
were made wrong and both suites stayed green. Fair hit: the PR invoked the standing
rule to justify a guard for docs/cli.md and left the same fact next door unguarded.
Rather than add a fourth guard the README now states the rule and links the docs
table, which is what "README orients, docs/ explains" asks for anyway. The new
anchor is checked by test_docs_links.

Also swept and clear, per that review: dl.bash (names only, no launch lines), both
devpod fakes and devpod_shim.py (no agent commands), test/e2e/*, the bench
scripts, interactive.rs's golden captures (claude-only, correctly unchanged), and
the herdr client, whose agent_in reads only the first program word so trailing
flags cannot reach it.

Both hardened guards were re-verified to bite on the exact inputs the review used.

One claim no test in this repo can reach, stated rather than implied: neither
codex nor gemini is installed in the container, so gemini --yolo --prompt-interactive <prompt> is checked as a string the fake devpod records, not as
a process that ran. gemini documents --yolo as exclusive with --approval-mode and
--prompt as exclusive with --prompt-interactive, and nothing conflicts --yolo
with -i.

@blooop
blooop merged commit ebb70eb into main Sep 7, 2026
15 checks passed
@blooop
blooop deleted the fix/584-full-auto-for-every-agent branch September 7, 2026 12:31
@blooop blooop mentioned this pull request Sep 7, 2026
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.

aid starts only claude in full auto; codex and gemini stop at their first prompt

1 participant