A scheduled job has no composer to pick a harness, model or effort in, so it
now says so itself: the leading YAML block of `.claude/agents/<job>.md` carries
`harness`, `model`, `effort` and `thinking`. `cron.run_config()` reads and
normalizes them and `_fire_cron_job` hands them to the same `_send_message`
path the composer uses, so a firing runs exactly like a hand-spawned session.
The keys are a subset of Claude Code's own agent frontmatter, so a job's prompt
file stays a usable `.claude/agents` subagent. Invalid values are dropped
rather than raised — a firing on the defaults beats a job that stops firing —
and the resolved config comes back on the job as `runConfig`, rendered as chips
in Settings → Cron so an unapplied key is visible. New jobs get a stub carrying
the default frontmatter. The store's per-job `model` is now only the fallback.
All four homelab jobs are set to Claude Code + sonnet + no effort.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>