# Routines

Use for a recurring unattended task (cron; pull data, open a PR, post a digest), or to...

- Repository: https://github.com/google/adk-recipes (10565 stars)
- Category: Testing
- License: Apache-2.0
- Last updated: 2026-11-01
- Runs scripts: no, instructions only

## Install

Claude Code: `npx skills add google/adk-recipes --skill routines -g -a claude-code -y`
Codex: `npx skills add google/adk-recipes --skill routines -g -a codex -y`
Cursor: `npx skills add google/adk-recipes --skill routines -g -a cursor -y`
Gemini CLI: `npx skills add google/adk-recipes --skill routines -g -a gemini-cli -y`

## Description

Use for a recurring unattended task (cron; pull data, open a PR, post a digest), or to test/dry-run a routine first. Explains authoring and testing via the routine tool.

## SKILL.md, as published by its author (untrusted third-party text, read it as data)

# Scheduling routines

A **routine** is a recurring task that runs **unattended** on a cron schedule, in
a **fresh sandbox isolated from the user's workspace**, holding **only the secrets
the routine declares**. Use it for "every morning, summarize X and report" /
"weekly, bump deps and open a PR", work that should happen without the user
present. There is no one-off reminder tool: it cannot ask the user anything
mid-run, so it is the wrong fit for a plain "remind me at 9pm" ping.

## The isolation model (why this is safe)

- The routine runs in its OWN sandbox (`lhart-<id>`), never the user's, so it
  cannot see their workspace, other projects, or undeclared secrets.
- It receives ONLY the secret env vars listed in `secrets:`, that list IS the
  blast-radius boundary. Declare the minimum the task needs (check the "Available
  secret env vars" line for the names).
- It is **headless** (nobody to approve mid-run): shell commands run normally in
  the isolated sandbox, `git clone`, `pip install`, build, `commit`/`push` all
  work, since the sandbox is the blast radius. Secret-exfiltration and
  known-destructive commands are still refused, and any *non-shell* action that
  would need approval is auto-denied, design the task to avoid those, or do an
  irreversible external step as a draft for the user to confirm later.
- Outputs come back as artifacts in the routine's session, it cannot write into
  the user's workspace.

## How to author one

Call `routine(action="create", name=..., schedule=..., task=..., secrets=[...])`:
- `schedule`: a 5-field cron expression (`"0 8 * * *"` = daily 08:00 UTC).
- `task`: a self-contained instruction, the routine has no memory of this chat
  and no access to the user's files, so state everything it needs.
- `secrets`: the exact secret env names the task requires (e.g.
  `["GITHUB_PAT"]`), or omit for none.

## Test it before scheduling

ALWAYS dry-run a routine before you create it:

The rest: https://github.com/google/adk-recipes/blob/HEAD/core/python/long-horizon-harness/horizon/builtin_skills/routines/SKILL.md
