A Agent A / docs
DOCUMENTATION

Background jobs

A background job is a task the agent runs on a schedule you choose, without you starting it each time. Every Monday at 9. Every quarter. The first of each month. Whatever cadence makes sense.

Agent-A---Jobs.gif

You describe what you want done and how often. The agent writes the task, picks a schedule, and asks once for approval. After that it runs on its own and stores the output so you can review every run.

What a job is (mechanically)

A Python script with a metadata header (name, description, schedule), saved to ~/workspace/jobs/<name>.py. The platform reads the header, schedules the script as the agent user inside your workspace, and stores every run's output (stdout + stderr, up to 50 KB each) in a run history you can browse from the Jobs tab.

You don't write the script. The agent does. You only describe the outcome and the cadence.

When to ask for a job vs a one-off

A job is the right artifact whenever the work has a cadence ("every Monday," "each quarter," "on the first of the month") or whenever it should happen automatically every time a trigger fires ("whenever we publish a product update"). Concrete shapes of ask that map cleanly to a registered job:

  1. Every Sunday, analyze my most recent Ahrefs site audit and open a PR in GitHub for priority fixes.
  2. Add newly-discovered listicle mentions to Firehose, then check for page changes each fortnight.
  3. Every quarter, identify blog posts with declining traffic and add refresh suggestions to our Notion editorial docs.
  4. On the first of each month, create a blog traffic performance report and publish to the #marketing Slack channel.
  5. Whenever we publish a product update, draft newsletter and social media copy in Notion.
  6. Each month, summarize our competitors' best new backlinks, then add them to Airtable.
  7. Generate a biweekly report on new competitor landing pages and assign it to the product team in Linear.
  8. Schedule a weekly analysis of our brand mentions in ChatGPT, then log negative themes in Airtable.
  9. Each week, scan our top keywords for newly-ranking Reddit discussions worth engaging with.
  10. Every Monday, summarize recently lost backlinks from high-authority domains and notify @john on Slack.

A one-off, by contrast, is anything you only want done once right now:

  • "Pull last week's data and give me the summary."
  • "Check this list of 100 URLs and tell me which ones return 404."

The heuristic is simple. If you say "every Monday," the agent builds a job. If you say "this Monday," it runs the work in chat once and stops.

Two session modes

When the agent writes a job, it picks one of two execution modes:

  • ephemeral — Each run is independent Python. Use this for standalone tasks: API calls, DB writes, report generation, deterministic data work. This covers most jobs.
  • continuous — The run shells out to the agent itself (pi -p "do X") with a persistent session file. Use this when the job needs reasoning that benefits from remembering previous runs (iterative analysis, ongoing summarization).

Most jobs are ephemeral. Continuous mode costs more (LLM calls every run) and is only worth it when the reasoning would benefit from history.

What approval looks like

The first time a job is registered, you see an approval card with: - Job name and description. - The cron schedule. - The session mode.

Owner or admin clicks once. After that, the job runs on schedule. You can pause, resume, manually trigger, or delete it from the Jobs tab.

Common schedules

Cadence Cron expression
Every 5 minutes */5 * * * *
Every hour at :00 0 * * * *
Daily at 9:00 UTC 0 9 * * *
Mondays at 8:00 UTC 0 8 * * 1
Twice daily (9 AM, 6 PM) 0 9,18 * * *

Cron times are UTC on this host. If you need a local timezone, the agent will either pick a UTC time that maps to your local time year-round, or add an in-script zoneinfo guard that only acts when local time is in the right window. (DST is annoying. The agent will tell you when it bites.)

Dependencies

If a job needs a Python package, the agent will: 1. Check whether it is already installed. 2. If not, request the install through the package approval flow. 3. Wait for owner/admin to approve the install. 4. Then register the job.

You will see one approval card for the package, one for the job. Aggregate requests batch nicely; ask for the whole flow in one go.

Talking to the agent from a job

For jobs that need reasoning, the script shells out to the agent:

import subprocess

result = subprocess.run(
    ["pi", "-p", "Pull this week's keyword deltas, draft a 4-bullet Slack summary, post to #seo-weekly"],
    capture_output=True, text=True, timeout=600,
)
print(result.stdout)

With session = "continuous", the agent remembers what it said last week and can build on it.

What jobs are running in this workspace

You can list them from the Jobs tab. As of this writing, the docs site itself is maintained by two:

  • Docs sync (every 30 min) — reads markdown from ~/workspace/docs/, renders to HTML, upserts into site_db so the public site can serve it.
  • Docs weekly digest (Mondays, gated to 10:00 Europe/Bucharest) — diffs the agent's memory, change log, and skills folder, asks the LLM what changed that customers should know about, and Slacks suggested doc edits to the maintainer.

Limits

  • A job times out after 1 hour. For longer work, split it into stages or write intermediate state to the database.
  • stdout and stderr are capped at 50 KB per run. Anything bigger should go to a file or database row.
  • Schedules are managed by the platform after approval. To change a schedule, the agent registers a new job and removes the old one. It does not silently edit cron.

Under the hood. Each job is a row in the platform's job table plus a crontab entry. The runner shells the script with stdin/stdout/stderr captured, sets a JOB_RUN_ID env var, and writes the run record back. If the script imports anything not installed system-wide, the run fails fast with a clear error in the run history.

Last updated 2026-05-29