Knowledge · Development tools

Automating Codex Android Checks Without Always Approve

Finding why Gradle tests stopped and standardizing verification without broadening permissions

A real Android Gradle troubleshooting case: move caches inside the workspace, scope tests to Debug, and use a project verification script instead of broad approval rules.

In the previous article, I described how enabling Codex Auto-review reduced the number of times development stopped for approval prompts. But similar prompts kept appearing during Android development.

Related readingWhen Codex Keeps Stopping for Approval

How Codex Auto-review reduced repeated approval interruptions in remote development, and why approval policies are different from sandbox permissions.

They appeared while running Gradle tests, building a Debug APK, changing code, and running the tests again.

The approval dialog included an "Always approve" option. Choosing it might have reduced interruptions immediately, but I wanted a different solution.

I wanted routine verification to proceed without treating Release signing or production deployment as automatically permitted work.

Three approval requests, one question

The requests looked roughly like this:

RequestIntended purposeWhy did it need attention?
git diff --check && ./gradlew testCheck the diff and run all testsExternal cache writes and Release-task dependencies
./gradlew assembleDebugBuild a Debug APKAn additional permission request in that environment
git diff --check && ./gradlew testRepeat the tests after changesThe original issue appeared again

An approval dialog alone does not prove that every request had exactly the same technical root cause. But I could reproduce the repeated interruption associated with the broad test task.

At first I suspected the Auto-review allowlist. But broadly approving commands that begin with gradlew could permit operations far beyond the checks I actually intended. I decided not to do that.

I asked Codex to find the cause, not to expand permissions

An important change was reframing the prompt.

Rather than just saying that approval prompts were inconvenient, I requested a more specific investigation:

Check the current settings and identify the real reason for each approval. Run local verification within the existing sandbox wherever possible. Do not broadly allow every bash, gradlew, npm, or git command. Review dangerous operations without actually executing them. If the approval policy is not the cause, do not change it.

Codex inspected the execution environment instead of immediately changing settings, and found two problems.

Cause 1: The Gradle cache was outside the workspace

At the time, Gradle tried to create a lock file inside a global cache directory under the user's home directory. But Codex was running in a workspace-write sandbox with restrictions on writing outside the workspace.

Running the test therefore attempted a write outside the permitted location, producing a read-only filesystem error.

The solution was not to disable the sandbox. It was to configure the execution environment to keep the cache inside the project.

Cause 2: The full test task pulled in Release signing

After changing the cache location, the test proceeded further. This time, however, the broad test task depended on Release-related build work and required signing material.

What I wanted to verify was Debug unit tests, not a signed Release APK. Running the entire test task was unnecessary.

Narrowing the task made the tests succeed:

GRADLE_USER_HOME="$PWD/.gradle-user-home" \
ANDROID_USER_HOME="$PWD/.android-user-home" \
./gradlew :app:testDebugUnitTest \
  --no-daemon --max-workers=1

I confirmed BUILD SUCCESSFUL at this stage. But one successful command is not a permanent fix. The next Codex conversation could revert to the broader command and reproduce the same interruption.

Make the procedure reusable

In a second request, I asked Codex not to stop at a diagnosis. I wanted a reusable verification script and written instructions inside the project.

The Android project gained this command:

scripts/verify-android.sh all

It runs a defined sequence:

OrderCheckPurpose
1git diff --checkCheck whitespace and diff formatting
2app:testDebugUnitTestAndroid Debug unit tests
3filter-engine:testFiltering engine tests
4app:assembleDebugBuild the Debug APK

Gradle and Android user data paths were redirected into the project. The script became the documented default Debug verification workflow in AGENTS.md. To reduce memory pressure, it also kept --no-daemon --max-workers=1.

The script deliberately excluded full Release builds, signing, and production deployment. That boundary was central to the change.

Results: successful checks without new approval rules

The standardized script produced the following results:

CheckResult
Diff formattingPassed
Android Debug unit testsPassed
Filtering engine testsPassed
Debug APK buildPassed
Additional approval prompts during that runNone
Writes outside the workspaceNone
Release signing or production deploymentNot performed
Existing sandbox and approval policyUnchanged

Android Gradle Plugin still warned about reading some locations under the user's home directory, but the warnings did not prevent the build. I saved the script and project instructions in the private repository for reuse.

There are important limits to this result. I had not separately verified that a completely new Codex session would automatically follow the AGENTS.md instruction and reproduce the same outcome. Passing Debug tests and building a Debug APK does not prove that Release signing or real-device behavior has been validated.

How is this different from Always approve?

"Always approve" approachApproach chosen here
Permit a command patternFix why the command needed extra access
Manage a wider approval ruleKeep sandbox and approval settings unchanged
Watch for risky commands with similar namesSeparate Debug verification from Release work
Reduce repeated promptsStandardize cache locations, commands, and project instructions

The new verification script still executes code. If the project or build configuration changes, the script needs reviewing again. It is not a complete security guarantee.

In this project, however, routine verification became possible without granting broader permissions.

What to check before enabling automatic approval

Initially I assumed that a more permissive approval policy would be the answer. The practical solution started elsewhere.

  1. Identify the command and environment where work stopped.
  2. Separate the cache-path issue from test-task scope.
  3. Keep the sandbox and choose Debug-only verification commands.
  4. Preserve the correct procedure in a script and project instructions.
  5. Confirm that tests and the Debug build complete without a new approval prompt.

The lesson is simple: before expanding what a tool may do, check whether the job can be done within the permissions it already has.

When instructing an AI coding tool, "find why this stopped and make the existing safe process repeatable" can be a better request than "approve everything automatically."

Related readingWhen Codex Keeps Stopping for Approval

How Codex Auto-review reduced repeated approval interruptions in remote development, and why approval policies are different from sandbox permissions.

Related readingCan I Keep Developing with AI When I Am Away from My Computer?

How I built a development workflow that does not depend on one laptop, and what I learned about version control, security, and deployment.

Related readingSet Up a Vibe-Coding Development Environment with WSL2, GitHub, and Cloudflare

A step-by-step guide to developing in WSL2 Ubuntu on Windows, managing code with Git and GitHub, and deploying a web service through Cloudflare's Git integration.

Written with AI assistance based on checks and verification performed during actual ONSEMO development.

Continue reading