# Scheduled remote agents can't see gitignored files

> Three /schedule routines proposed, two created, one declined. The recurring sweep would have read a gitignored folder — the remote agent can't see those.

**Canonical URL**: https://agentcookbooks.com/blog/scheduled-remote-agents-cant-see-gitignored-files/

**Published**: 2026-05-21

**Tags**: claude-code, automation

---

A scheduled remote agent — the kind you set up via `/schedule` to run on a cron, against your GitHub repo — sees exactly what GitHub sees. It doesn't matter how much state lives in your local working tree; if that state is gitignored, the remote checkout will be blind to it. This collides with at least one common Claude Code pattern: storing receipts, drafts, or evaluation data in a local-only directory like `receipts-drafts/` and then trying to schedule an agent to sweep that directory weekly. The skill docs don't mention it. I tripped on it trying to set up a routine, declined to ship the routine, and added a fallback note to the two routines I did create.

## What I ran

Invoked `/schedule` as step four of a broader harness audit. Three routines on the wishlist:

1. **+7d one-off**: verify the custom domain attachment landed cleanly and Search Console picked up the sitemap.
2. **+14d one-off**: scan the wiki for the bulk-imported skill receipts that were still showing as TODO placeholder text, in case any had been quietly upgraded.
3. **Recurring weekly**: run `/skill-evolve` against `receipts-drafts/` to flag receipts that had accumulated enough new entries to merit promotion.

## What happened

Two routines created cleanly, one declined with explanation. The skill returned trigger IDs for the ones that shipped (`trig_<redacted_1>` at `2026-05-06T06:00:00Z`, `trig_<redacted_2>` at `2026-05-13T06:00:00Z`). The third routine — the weekly sweep — got refused once I worked out the constraint.

The constraint: a scheduled remote agent runs against the **GitHub checkout** of the repo, not against the local working tree. Anything in `.gitignore` is invisible to the remote runner. In this project, `receipts-drafts/` is gitignored by design — the raw session notes are private, often contain operator-specific paths, and are explicitly only meant to be curated *into* wiki receipts after editing. So the entire input the recurring routine was supposed to read does not exist on the remote.

The skill output didn't flag this constraint. It would have happily scheduled the routine. Cross-referencing `.gitignore` was the only way to catch it before the first run hit a no-op.

The two routines that did ship work fine because:

- Routine #1 (web-only checks via `curl` / `WebFetch` against the live site) doesn't need any repo state.
- Routine #2 (read-only scan of `src/content/skills/*.md` for TODO placeholder text) reads only committed content, which the remote *can* see.

Both routine prompts got a small fallback paragraph: "If the private-repo checkout fails at runtime, fall back to the web-only path." That's belt-and-suspenders against auth issues at trigger time.

## Where it drifted

**`/schedule` doesn't surface its environment model anywhere.** The skill takes a prompt and a trigger time. The implicit assumption is that the remote agent has access to whatever a local agent does. It doesn't. Remote = whatever-is-on-the-default-branch-of-the-GitHub-repo. Period. There's no copy of the working tree, no copy of `.env*`, no copy of any gitignored folder.

If your workflow depends on local-only files — receipts, scratchpads, exports, secrets in `.env`, drafts in folders the repo doesn't track — none of them are reachable from a scheduled remote run. That includes anything in the project's own gitignored folders that the skill might naturally assume are part of the project: `receipts-drafts/`, `decisions/`, `data/`, `competitor-profiles/`, `.exports/`. The whole privacy layer this project leans on is invisible to the remote.

**Routine #3 was the receipt.** Routine #3 was the most obviously useful of the three on the wishlist. It was also the one that couldn't ship. The pattern to watch: every routine where the prompt mentions reading or sweeping a directory needs an answer to "is this directory committed?" before the schedule call.

## What I'd change

**Pre-flight: cross-reference the prompt against `.gitignore` before scheduling.** If the prompt names any path that matches a gitignore rule, decline the routine and explain. Single shell check, ~5 lines of pseudocode. Belongs in the skill itself.

**Document the environment model in the skill's quickstart.** One paragraph: "scheduled remote agents check out your repo from GitHub on each run. They see committed files only. Gitignored folders, local `.env*` files, and uncommitted working-tree state are not available."

**For local-only sweep workflows, use the local `/loop` skill or a desktop cron instead of `/schedule`.** Loops run in your current Claude Code session against the full local working tree. Cron + a wrapper script does the same. Scheduled remote agents are the wrong tool when the input lives outside the repo.