Codex automations: choose where tasks run and verify the result
Codex automations are scheduled tasks that can revisit a project without a fresh prompt each time. The first decision is where the task runs: the ChatGPT desktop app can access a local repository, while an eligible web task works with files, projects and connected services available to it online. Neither route proves that a schedule executed simply because you saved it.
This walkthrough configures one read-only project-change digest for a Git repository. It gives you a prompt, a safe Windows test fixture and four checks: a scheduled run with changes, a no-change run, a missing-input failure and a recovered run. The output is deliberately narrow so you can tell an actual execution from a plausible but unsupported summary.
Working configuration: a daily project-change digest
- Choose the execution location. Use a desktop project for local Git files, or a web task only if its repository context is available through an authorised connection or upload.
- Keep the job read-only. Allow repository inspection, but no edits, commits, network requests or deployments.
- Schedule 09:00 Europe/London daily. Record the timezone and the next-run time displayed in Scheduled. Verify the actual start separately.
- Check real scheduled runs. Inspect the run entry and captured command output for the changed, unchanged, blocked and recovered conditions.
| Where it runs | Inputs available | Most important limitation |
|---|---|---|
| Desktop project, local checkout | Files and Git history in the selected directory, within sandbox permissions | The computer, app and project must be available when the task runs. |
| Desktop project, isolated worktree | A separate Git worktree for the selected repository | Uncommitted changes in your main checkout may be absent. Worktree output is not automatically a persistent report in your main branch. |
| ChatGPT web, eligible task | Uploaded context and authorised connected tools | It cannot browse an arbitrary folder on your computer. A GitHub connection must expose the required repository. |
| Codex CLI or IDE extension | Useful for preparing and manually testing the instructions | Neither provides the native Scheduled management interface. |
For this exercise, use the desktop app in local-project mode against a disposable repository. The task itself will not write files, and local mode lets you temporarily remove a required file to test recovery. For a real project, an isolated worktree is usually preferable when any edits might occur. Use the native Windows PowerShell environment for the commands below; a WSL project would need shell equivalents. If your source is only in a connected Cloud service, use the web route instead of trying to make an online task read your laptop.
Build a fixture with changes Codex can verify.
Create a small repository rather than pointing the first unattended task at a production WordPress checkout. The following PowerShell commands generate two harmless commits and a required scope file. They change only the new fixture directory.
$repo = Join-Path $HOME 'codex-digest-fixture'
New-Item -ItemType Directory -Force $repo | Out-Null
Set-Location $repo
git init
git config user.name 'Digest Fixture'
git config user.email 'fixture@example.invalid'
New-Item -ItemType Directory -Force docs | Out-Null
'Include committed changes only. Do not modify files.' | Set-Content docs\digest-scope.md
'# Fixture project' | Set-Content README.md
git add .
git commit -m 'docs: create digest fixture'
'Example release note' | Add-Content README.md
git add README.md
git commit -m 'docs: add release note'
Open this directory as the desktop project’s working folder. Before scheduling anything, confirm that git rev-parse --show-toplevel points to the fixture, and that git status --short is empty. The digest will use commit history, not uncommitted edits or an Agent’s recollection of earlier chats.
Use an instruction that cannot silently turn missing evidence into a summary
Create a standalone task in Scheduled for the fixture project. Choose the local project rather than a worktree for this particular fault-injection test, set the daily schedule and paste the following prompt. A standalone run should return its findings to Scheduled; no external document or email destination is needed.
Produce a READ-ONLY change digest for the selected Git project.
Report timezone: Europe/London. Do not edit files or use the network.
1. At the start, run Get-Date -Format o and retain its output.
2. Require docs/digest-scope.md. If missing, stop with
BLOCKED_MISSING_INPUT. Do not guess its contents.
3. Run git rev-parse --show-toplevel, git rev-parse HEAD,
git branch --show-current, git status --short, and
git log --since="24 hours ago"
--max-count=20 --format="%h | %cI | %s".
4. If Git or file access fails, stop with BLOCKED_PERMISSION
and the exact failed check. Do not use memory as a fallback.
5. For successful access, report CHANGES_FOUND or NO_CHANGES.
List commit IDs, timestamps and subjects for found commits.
State that uncommitted work is excluded. If the 20-commit
cap is reached, mark the digest POSSIBLY_TRUNCATED.
6. At the end, run Get-Date -Format o again.
7. Return exactly: Status, Project, Branch, HEAD, Started,
Finished, Commits, Limitations, Next action.
Never claim that tests ran, a deployment succeeded, or the
scheduled trigger fired merely because this prompt was executed.
The scheduled occurrence time must be verified in Scheduled.
Test the prompt once manually to catch an incorrect path or denied Git command, then leave the scheduled task to run at its next due time. Manual success validates the instructions, not the scheduler. OpenAI’s Scheduled tasks documentation explains the desktop and web execution paths, task history and unattended sandbox behaviour.
What a useful digest should return, including an honest no-change result
A successful run should identify the actual project root and HEAD, then list the recent commits it could read. The following is an output shape, not a recorded run; commit identifiers and timestamps must be supplied by the live execution.
Status: CHANGES_FOUND
Project: [verified Git root]
Branch: [reported branch or detached HEAD]
HEAD: [actual commit SHA]
Started: [first command timestamp]
Finished: [last command timestamp]
Commits: [real short SHA | commit time | subject lines]
Limitations: Committed history only; 24-hour rolling window
Next action: Human review of listed changes
On a later scheduled day with no commits in the preceding 24 hours, the same task should return NO_CHANGES and zero matching commits. That is a result, not an error. It should still include the repository identity and run timestamps. A digest that says “nothing changed” after losing repository access has failed: its correct status is BLOCKED_PERMISSION or BLOCKED_MISSING_INPUT.
The rolling window is a conscious compromise. It is easy to inspect and does not require writing a checkpoint file, but it can miss changes if the machine is offline for a day. A 48-hour window reduces that risk at the expense of duplicate entries. For release-critical tracking, use a durable last-processed commit SHA with explicit checkpoint updates and recovery rules, or rely on repository-native CI instead. Do not quietly present a 24-hour digest as a complete change audit.
Prove the scheduler ran, not merely that the prompt works
Record the displayed next occurrence before the due time, then compare it with the actual task entry in Scheduled. Capture the desktop app version, selected model, project path, run location and permission mode. The Agent’s Started and Finished values come from clock commands; the scheduled-for value comes from the scheduling interface, not from a date the Agent invents.
| Scheduled test | Controlled condition | Evidence needed |
|---|---|---|
| Changes found | Two fixture commits exist within the 24-hour window. | Scheduled run entry, actual start and finish, correct Git root, HEAD and commit subjects. |
| No changes | Keep the fixture unchanged until both commits fall outside the 24-hour window. | A separate scheduled run with NO_CHANGES and zero commits, not a reused earlier response. |
| Missing input | Temporarily rename docs/digest-scope.md in the local fixture before a due run. | A new scheduled run reporting BLOCKED_MISSING_INPUT, without repository edits or invented content. |
| Recovery | Restore the original filename before the next scheduled occurrence. | A later scheduled run reading the file again and returning a normal status. |
Do not use Run now as proof of automatic dispatch. It is a useful diagnostic, but the publication-quality test requires a new run associated with the configured schedule. Capture screenshots or exported run details showing the schedule, task history and outputs. If the interface lacks a start or completion timestamp, record the missing field rather than filling it in from assumption.
Three reliability traps hidden by a reassuring task card
Timezone labels are not execution evidence
Use the IANA timezone Europe/London in your test notes and compare the displayed next-run time with the actual run timestamp and UTC offset. Practitioner reports describe scheduled tasks firing at an unexpected UTC-adjusted hour or twice after a timezone change. That does not prove every installation is affected, but it makes a single screenshot of “Daily at 09:00” inadequate, particularly around the British Summer Time changeover.
See more of our reporting in Google Top Stories, AI Overviews and AI Mode.
Sleep, offline time and missed runs can create gaps.
A local scheduled job needs the machine and desktop app running. Do not assume a missed occurrence will be replayed exactly once after the computer wakes. Reports of skipped runs and unexpected catch-up activity make it safer to inspect history after outages and compare Git commits back to the last confirmed successful digest. A web task avoids reliance on your laptop, but only when its connected inputs provide the source data.
Unattended permissions can make a small digest an expensive risk.
Scheduled tasks execute without someone approving each operation. Keep this example read-only with network access disabled. An isolated worktree reduces interference with unfinished edits but does not grant remote access or make an unattended command safe by itself. If you later add tests, file writes, or a GitHub integration, retest the permission failures and expected side effects.
Model selection, reasoning effort and the volume of repository context also affect usage. Keep the prompt bounded to 20 commits and review your plan’s limits using our Codex pricing guide. If you run the same digest across repositories, a narrow, versioned procedure can be packaged as a skill; our Codex Skills verification tutorial explains how to check whether the intended instructions actually loaded.
When to use Codex scheduling rather than a conventional CI job
Choose a scheduled Codex digest when you want a human-readable summary of accessible project activity and can review its run history. Choose GitHub Actions, a server cron job or another deterministic scheduler when every missed run must be accounted for, an artefact must always be stored in a known location, or a failed check must block a deployment. You can still ask Codex to interpret CI results, but the authoritative pass or fail should come from the tool that performed the check.
For this example, acceptance means four distinct scheduled observations: changes found, no changes, missing input and recovery. Until those runs have been captured, the configuration above is a reproducible test protocol, not evidence that a particular Codex installation delivered the digest reliably.


