Skip to content

Job Scheduler

Define tasks as JSON with cron schedules. Instar spawns Claude Code sessions to execute them.

{
"slug": "check-emails",
"name": "Email Check",
"schedule": "0 */2 * * *",
"priority": "high",
"enabled": true,
"execute": {
"type": "prompt",
"value": "Check email for new messages. Summarize anything urgent and send to Telegram."
}
}
TypeDescription
promptSpawns a Claude Code (or Codex) session with the given prompt
scriptRuns a shell command
skillExecutes a slash command
agentmdResolves to .instar/jobs/<origin>/<slug>.md whose markdown body is the job spec. Lets job definitions live as full markdown files with YAML frontmatter instead of inline JSON. The fourteen built-in default jobs ship as agentmd files.

Jobs have low, medium, or high priority. Higher priority jobs are executed first when multiple jobs are due simultaneously.

Each job can specify a model:

  • opus — Complex reasoning, analysis, long-form work
  • sonnet — General tasks, moderate reasoning (default)
  • haiku — Quick checks, simple tasks, high-frequency jobs
{
"slug": "health-check",
"schedule": "*/5 * * * *",
"model": "haiku",
"execute": {
"type": "prompt",
"value": "Run health diagnostics and report any issues."
}
}

Jobs declare a supervision field that controls how each step is validated:

  • tier0 — Raw programmatic. No LLM validation. Fast, cheap, silent failures.
  • tier1 — LLM-supervised. A lightweight model (Haiku) validates each step. Observed failures.
  • tier2 — Full intelligent. A capable model (Sonnet/Opus) handles reasoning end-to-end. Handled failures.

The supervision tier is independent of the execution model — tier1 may use Haiku for validation while the job runs on Sonnet, for instance. See docs/LLM-SUPERVISED-EXECUTION.md for the design.

The scheduler reads from a shared QuotaTracker and shedds load tier-aware as quota tightens. Configure via scheduler.quotaThresholds:

BucketAction
normalFull scheduling
elevatedDefer Opus-tier jobs
criticalDefer Sonnet-tier jobs as well
shutdownPause everything except health-check

This lets you keep critical safety jobs alive even when you’re hammering against the daily cap. See the observability page for how the underlying quota tracker works.

When the host wakes from sleep, the scheduler reaps any pending runs older than wakeReaper.thresholdMultiplier × expectedDurationMinutes. This prevents a stampede of overdue jobs from firing all at once after a long suspend.

Job gates (preconditions evaluated before the job body runs) can fail transiently. The scheduler retries gates up to gateRetries times (default 3) with gateRetryDelayMs between attempts (default 5 s). Persistent gate failures surface as a degradation rather than a stuck job.

Instar ships fourteen built-in jobs that install on instar init and refresh on every update. See the default jobs reference for the complete list with schedules and supervision tiers.

Older agents may have enabled quota tracking via instar add quota. The new path is automatic — quota awareness is built into the scheduler and consults the QuotaTracker directly, no opt-in required.

Terminal window
# Add a job
instar job add --slug daily-summary --name "Daily Summary" \
--schedule "0 9 * * *" --priority medium
# List jobs
curl localhost:4040/jobs
# Trigger a job manually
curl -X POST localhost:4040/jobs/daily-summary/trigger \
-H 'Authorization: Bearer YOUR_AUTH_TOKEN'

Each job gets its own topic in your Telegram group. Job output is posted to its topic automatically, creating a living dashboard of agent activity.