# Scheduling autoresearch every 3 hours

Four ways. Pick one based on where you want it to run.

## Option 1 — macOS launchd (recommended for your MacBook)

Reliable, native, runs even after reboot if the laptop is awake at the right time. Doesn't run when the laptop is asleep — that's the main caveat.

```bash
# Install
cp /Users/anilchinchawale/github/XDCNetwork/XDC-Geth/xdpos-autoresearch/scheduler/com.xdc.autoresearch.plist \
   ~/Library/LaunchAgents/com.xdc.autoresearch.plist

# Activate
launchctl load -w ~/Library/LaunchAgents/com.xdc.autoresearch.plist

# Verify it's loaded
launchctl list | grep xdc.autoresearch

# Trigger an immediate run (don't wait 3h for the first one)
launchctl start com.xdc.autoresearch

# Watch the log
tail -f ~/github/XDCNetwork/XDC-Geth/xdpos-autoresearch/log/scheduled/launchd.stdout
```

The plist runs `tick.sh` at boot+3h cadence. To stop:

```bash
launchctl unload -w ~/Library/LaunchAgents/com.xdc.autoresearch.plist
```

**Important:** the plist's `EnvironmentVariables/PATH` includes `/opt/homebrew/bin:/usr/local/bin`. If your `claude` CLI is installed somewhere else, run `which claude` and add that directory to PATH in the plist.

If you want it to run even when the laptop is asleep, prefix `tick.sh`'s invocation with `caffeinate -s -i` in the plist's `ProgramArguments`. That keeps the system awake just for that one tick.

## Option 2 — cron (simpler, but Apple deprecates it)

```bash
# Edit the user crontab
crontab -e

# Add this line:
0 */3 * * * /Users/anilchinchawale/github/XDCNetwork/XDC-Geth/xdpos-autoresearch/tick.sh >> /Users/anilchinchawale/github/XDCNetwork/XDC-Geth/xdpos-autoresearch/log/scheduled/cron.log 2>&1
```

That fires at 00:00, 03:00, 06:00, 09:00, 12:00, 15:00, 18:00, 21:00 daily. If you want strict "every 3h from when I install it" semantics, use launchd instead — cron's "every 3h" is wall-clock-aligned, not interval-from-install.

Note: cron on macOS needs full-disk-access permission for the cron daemon to read your `~/Library/LaunchAgents/` peer files. System Preferences → Security & Privacy → Privacy → Full Disk Access → add `cron`.

## Option 3 — xdc07 systemd timer (most reliable, runs 24/7)

Best if you want the loop to run regardless of laptop state. Needs `claude` CLI installed on xdc07 and an `ANTHROPIC_API_KEY` set.

```bash
# On xdc07:
sudo cp /opt/xdc/xdpos-autoresearch/scheduler/xdc-autoresearch.service /etc/systemd/system/
sudo cp /opt/xdc/xdpos-autoresearch/scheduler/xdc-autoresearch.timer   /etc/systemd/system/

# Set the API key via drop-in (so it's not in the unit file in the repo)
sudo systemctl edit xdc-autoresearch.service
# In the editor, paste:
# [Service]
# Environment=ANTHROPIC_API_KEY=sk-ant-your-key-here

# Reload + enable + start
sudo systemctl daemon-reload
sudo systemctl enable --now xdc-autoresearch.timer

# Verify the timer is scheduled
systemctl list-timers | grep xdc-autoresearch

# Trigger an immediate run
sudo systemctl start xdc-autoresearch.service

# Watch the log
tail -f /var/log/xdc-autoresearch.log
journalctl -fu xdc-autoresearch.service
```

The timer's `Persistent=true` means if xdc07 reboots, the next-due run fires on boot. The 2-minute `RandomizedDelaySec` desyncs multiple hosts so they don't all hit GitHub at the same second.

To stop: `sudo systemctl disable --now xdc-autoresearch.timer`.

## Option 4 — Cowork scheduled-task skill (if you stay in Cowork)

Cowork ships a built-in `schedule` skill that creates a scheduled task you can run on demand or on an interval. From the Cowork session:

```
/schedule
```

…then describe the task: "every 3 hours, run /Users/anilchinchawale/github/XDCNetwork/XDC-Geth/xdpos-autoresearch/tick.sh and report the score." Cowork will configure it.

This option only runs when Cowork is up and the desktop app is running, similar to launchd's "must be awake" caveat. Best for quick experiments rather than long-term unattended ops.

## What runs each tick (`tick.sh`)

Each tick is intentionally idempotent and safe to interrupt:

1. **Measure** the current `score` and log to `log/scheduled/<timestamp>/before.json`.
2. **Dirty-tree check.** If the patient working tree has uncommitted changes (e.g., from the autoresearch run we just did, or your in-progress edits), the tick **skips git pull and skips claude -p**. It just logs the score and exits. This prevents scheduled ticks from stomping on unreviewed work.
3. **Git fetch** `origin/xdc-network`. If new commits arrived since the last tick, fast-forward the local ref. Re-measure to detect regressions from new commits — if score drops, log a `REGRESSION` entry to `timeline.log`.
4. **If score < max**, invoke `claude -p --model claude-opus-4-7 < program.md`. The agent reads program.md, picks the lowest-scoring failing check, makes a surgical edit, re-measures.
5. **Auto-revert on regression.** If the post-iteration score is *lower* than before, `git checkout -- .` is run on the patient to revert the change. The tick logs a `REGRESSED` entry.
6. **Append** a one-line entry to `log/scheduled/timeline.log`. Watching that file gives you a one-line-per-3-hours diary of what's happening.

## Timeline log format

```
$ cat xdpos-autoresearch/log/scheduled/timeline.log
2026-04-26T03:00:00Z DIRTY score=115 files=12 (skipped)
2026-04-26T06:00:00Z DIRTY score=115 files=12 (skipped)
2026-04-26T09:00:00Z MAX score=115/115
2026-04-26T12:00:00Z REGRESSION before=115 after_fetch=110     ← new PR introduced a regression
2026-04-26T12:00:42Z IMPROVED 110->115 (+5)                    ← claude -p fixed it
2026-04-26T15:00:00Z MAX score=115/115
```

Each line tells you what happened and whether human review is needed.

## What to do with the output

Each tick that produces a code change saves the diff to `log/scheduled/<timestamp>/diff.patch`. Review and commit at your leisure:

```bash
ls -la /Users/anilchinchawale/github/XDCNetwork/XDC-Geth/xdpos-autoresearch/log/scheduled/
# Each timestamped dir has: before.json, after.json, agent_transcript.txt, diff.patch (if changed), run.log

# Apply a tick's diff to a review branch
cd /Users/anilchinchawale/github/XDCNetwork/XDC-Geth
git checkout -b autoresearch-review
git apply xdpos-autoresearch/log/scheduled/2026-04-26T03:00:00Z/diff.patch
git diff  # review
```

## Recommended setup for your situation

You're on a MacBook that you keep open most of the workday. Use **Option 1 (launchd)** as the primary, plus **Option 4 (Cowork schedule)** as a backup for during sessions.

For long-running unattended work where you really want the loop to keep going even when you're not around, **Option 3 (xdc07 systemd)** is the right call — but it's also the most invasive (claude CLI on the server, API key management).

A pragmatic setup: launchd on the laptop running every 3h during normal hours, and an xdc07 systemd timer firing once per night during low-activity hours (configure with `OnCalendar=03:00` instead of `OnUnitActiveSec=3h`).

## When to stop the schedule

The autoresearch loop's job is to keep `measure.sh` at 115/115. Once that's stable for a while AND validation gates (`validate.sh` Stage 5/6) are landing through CI rather than the autoresearch loop, the scheduled tick is mostly insurance against regressions.

You can keep it running indefinitely (it's cheap; ~$0.10/tick at most) or unload it when the project graduates to standard CI-based regression detection. Your call.
