{"slug": "three-things-already-in-your-claude-code-that-most-people-haven-t-touched-agents", "title": "Three things already in your Claude Code that most people haven't touched: routines, background agents, stacked skills.", "summary": "An engineer detailed how to set up routines, background agents, and stacked skills in Claude Code, sharing a repo-health check routine that runs scheduled cloud agents to verify README instructions. The routine uses a self-contained prompt, cron expressions in UTC, and a one-off run_once_at option for testing, with notifications and transcripts available via the routine page.", "body_md": "# Three things already in your claude code that most people haven't touched. The setup for each, from my real workflow.\n\nA routine is a scheduled **cloud** agent. It is not a local cron job. Each run spawns an isolated session in Anthropic's cloud with its own git checkout. It cannot see your laptop, your local files, or your local env vars. Everything it needs has to come from the repo it clones and from the prompt.\n\nHere is the repo-health check I set up, step by step.\n\nMine: go through every project in `ai-weekend-builds`\n\nand confirm the install and run steps in each README actually work.\n\nThe prompt is the part that matters most. The cloud agent starts with zero context, so it has to be self-contained. Mine says, in order: map the repo, read each README, extract the exact documented commands, actually run them, record the real error output. Then a list of things to flag — missing README, commands pointing at files that don't exist, missing `.env.example`\n\nwhen the code reads env vars, lockfile out of sync, version requirements that conflict with what the code needs.\n\nTwo lines that do a lot of work:\n\n```\nDo NOT fix anything. Do NOT commit, push, or open a pull request. This run is read-and-report only.\nBe specific and paste real command output rather than summarizing it.\n```\n\nWithout the first, the agent will helpfully start editing your repo. Without the second, you get \"a few projects had issues\" instead of a stack trace.\n\nCron is five fields, **always in UTC**, minimum interval one hour. `*/30 * * * *`\n\ngets rejected.\n\n```\n0 9 * * 1-5     weekdays at 9am UTC\n0 12 * * *      daily at 12:00 UTC\n30 14 * * 1     Mondays at 2:30pm UTC\n0 8 1 * *       first of the month, 8am UTC\n```\n\nI'm in Europe/Belgrade, which is UTC+2 in summer. So 7am for me is `0 5 * * *`\n\n. Do the conversion, don't eyeball it.\n\nFor a one-off you use `run_once_at`\n\ninstead of `cron_expression`\n\n, an RFC3339 UTC timestamp that must be in the future:\n\n```\n\"run_once_at\": \"2026-07-31T15:54:30Z\"\n```\n\nThe one-hour minimum does **not** apply to `run_once_at`\n\n. That's the escape hatch when you want to watch it fire in ten minutes instead of waiting until tomorrow. I used exactly that to test this routine before switching it to a daily schedule.\n\n```\n{\n  \"name\": \"Repo health — ai-weekend-builds\",\n  \"run_once_at\": \"2026-07-31T15:54:30Z\",\n  \"enabled\": true,\n  \"notifications\": { \"channel\": { \"email\": false, \"push\": true, \"slack\": false } },\n  \"job_config\": {\n    \"ccr\": {\n      \"environment_id\": \"env_...\",\n      \"session_context\": {\n        \"model\": \"claude-sonnet-5\",\n        \"sources\": [\n          { \"git_repository\": { \"url\": \"https://github.com/kju4q/ai-weekend-builds\" } }\n        ],\n        \"allowed_tools\": [\"Bash\", \"Read\", \"Write\", \"Edit\", \"Glob\", \"Grep\"]\n      },\n      \"events\": [\n        { \"data\": {\n            \"uuid\": \"<fresh lowercase v4 uuid>\",\n            \"session_id\": \"\",\n            \"type\": \"user\",\n            \"parent_tool_use_id\": null,\n            \"message\": { \"role\": \"user\", \"content\": \"YOUR PROMPT HERE\" }\n        } }\n      ]\n    }\n  }\n}\n```\n\nNotes from actually doing this:\n\n`sources`\n\nis what gets cloned. No repo listed, no repo in the sandbox.`allowed_tools`\n\nneeds`Bash`\n\nif the agent is going to run install commands. Mine has it. It does not need`WebFetch`\n\n/`WebSearch`\n\n, so I left those out.- The\n`uuid`\n\nis a fresh v4 you generate yourself, per routine. - The environment id comes from your available environments. Most people have one, called Default.\n\nTwo places.\n\n**Push notification**, from `notifications.channel.push: true`\n\n. That's the one I use. Email and Slack are the other two channels and they're independent booleans, so you can have all three or none. If you set none, the run still happens and you just have to go look.\n\n**The routine page**, at `https://claude.ai/code/routines/{ROUTINE_ID}`\n\n. The create call returns the id. Every run's full transcript lands there, so you can read what the agent actually ran, not just its summary.\n\n- Connectors get attached even when you don't ask. My repo-health routine came back with Gmail, Google Calendar, and Claude Code Remote attached, because they're connected at the account level. Worth knowing if you care what a scheduled agent can reach.\n- You can't delete a routine from the CLI. Only from\n`https://claude.ai/code/routines`\n\n. You*can*disable it with`\"enabled\": false`\n\n. - A one-shot auto-disables after it fires and shows\n`ended_reason: \"run_once_fired\"`\n\n. To reuse it, update it with a new`run_once_at`\n\nor swap in a`cron_expression`\n\n. - The agent runs in the cloud. If your project needs a database, an API key, or a local service, it will fail there and pass on your machine. Write the prompt so a failure to install is a\n*finding*, not a crash.\n\nstart with the thing you do manually every morning.\n\nThe flow: you hand a task to a background agent, keep working, and get a notification when it's done. You are not sitting and watching it.\n\n**Hand off the task.** You describe the work and it runs in its own context, separate from yours. You keep going in the main session.\n\n**Isolate it if it writes files.** A background agent can run in its own git worktree, meaning a fresh checkout on disk. This matters the moment you have more than one agent editing files, or you want your working tree untouched while it works. It costs a little setup time and disk per agent, so use it when there's actual write contention, not by default.\n\n**Say what \"done\" means, explicitly.** This is the part people skip. Committing, pushing, and opening a draft PR are not automatic. They happen because the prompt told the agent to do them, in those words. Something like:\n\n```\nWhen the work is complete: commit with a descriptive message,\npush the branch, and open a DRAFT pull request against main\nwith a summary of what changed and what you did not cover.\n```\n\nDraft, specifically. A draft PR is a review surface, not a merge request. It means you can hand off work freely without anything landing while you're not looking.\n\n**The notification.** Background work reports back into the session that started it when it finishes. You get told; you don't poll. Polling on a timer for work that already notifies you is wasted effort.\n\nCheck these in order, cheapest first:\n\n**The prompt.** Does it actually say to open a PR? An agent that was asked to \"fix the failing test\" fixes the failing test. Most of the time this is the whole answer.**Push permission in the environment where the agent ran.** A cloud agent's sandbox has its own git credentials. If it can't push the branch, it can't open the PR, and the failure shows up as a push error partway down the transcript rather than at the end.**Explicit forbidding.** If your prompt or a project instruction says not to commit or push without asking — mine says exactly that for the repo-health routine, on purpose — the agent will obey it and stop. Read your own instructions before blaming the tool.\n\nRead the run transcript on the routine page. The reason is almost always sitting in it.\n\nSkills are packaged instructions for a specific kind of task: a review checklist, a deploy sequence, a house style. You invoke one with `/name`\n\n.\n\nStacking means running several in one line so they compose into a single pass instead of separate ones.\n\nThree skills, one argument line, one pass:\n\n```\n/q-research /q-building /q-thinking apply research-workflow and blind-spot-finder\nto this task: research what shipped in claude code this month and identify the most\nunderused feature, then draft a short post about it. Then critique against\n~/.claude/TASTE.md and fix violations before showing me.\n```\n\nAll three skills load into the same turn. The argument text goes to each one. They do not run as three separate passes handing files to each other; they arrive as three sets of instructions over a single piece of work, and you name which technique you want from each. That last part matters. `q-thinking`\n\nalone ships six techniques. Without naming `blind-spot-finder`\n\n, you are letting the model pick.\n\nWhat came back was one pass with four labelled stages: the research structure, the findings, the gaps, then the taste critique. Research fed the draft. The draft went through the taste file. No copy-paste between steps.\n\nI added skills to `.claude/skills/`\n\nand they did not exist. Not an error message, just nothing when I typed `/`\n\n.\n\nThe skill list is read when the session starts. Adding a directory to a running session does nothing. Restart, then the skill is there.\n\nThis is the entire bug most of the time. Before debugging your frontmatter, quit and reopen.\n\nEvery `SKILL.md`\n\nneeds a YAML block at the very top, before anything else:\n\n```\n---\nname: q-thinking\ndescription: Use this skill when the user needs to understand a problem before\n  solving it. Activate for complex situations where the answer is not clear, where\n  assumptions need surfacing, or where the user feels stuck or overwhelmed.\n---\n```\n\nTwo keys. `name`\n\nis what you type after the slash and it has to match the directory name. `description`\n\nis not documentation. It is the matching text: the model reads it to decide whether this skill applies to what you just asked. Write it as trigger conditions, not as a summary of the contents. Mine all start with \"Use this skill when\" and then list the situations. That phrasing is doing work.\n\nMissing block, or a block that is not the first thing in the file, and the skill is invisible. Same symptom as the restart problem, different cause, which is why you check the restart first.\n\nLayout that works:\n\n```\n.claude/skills/\n  q-thinking/\n    SKILL.md          <- frontmatter here\n    techniques/\n      blind-spot-finder.md\n      complexity-mapper.md\n```\n\n`SKILL.md`\n\nis the index. Keep the long technique text in separate files and let the skill point at them. It loads what it needs instead of everything.\n\nThe last skill in the stack is not a skill. It is a file.\n\n`~/.claude/TASTE.md`\n\nholds my content rules: banned words, banned punctuation, anti-preferences, and four things every piece has to do. It ends with one instruction:\n\n```\nBefore presenting any output, review it against every rule in this file.\nIf it violates a rule, fix it before showing me. If unsure whether something\nviolates a rule, flag it and ask.\n```\n\nPutting it last in the stack means it runs on the finished draft rather than on my prompt. The research and the writing happen without it in the way, then everything passes through it before I see it.\n\nThe clause that earns its place is the second one. On this run, one of my rules is \"test it before teaching it.\" The draft post was about a feature it had confirmed existed but had never actually run. Instead of quietly shipping it or silently dropping the claim, it flagged the gap and asked whether to run a real test first. A gate that only deletes violations would have deleted the interesting sentence. A gate that can ask hands the decision back to me.\n\nWorth knowing: my own rules ban em dashes, and the sections above this one are full of them. The gate applies to what it writes, not to what I already wrote.\n\nWhen the output of each stage is the input to the next and you want them to share context, research feeding a draft, the draft passing through a taste file, stack them. When the steps are independent and you would want to inspect or correct the result between them, run them separately.\n\nThat's the whole rule. Stack when the handoff is the point. Don't stack when you want a checkpoint in the middle.\n\nBuilt by @kju4q, more at github.com/kju4q", "url": "https://wpnews.pro/news/three-things-already-in-your-claude-code-that-most-people-haven-t-touched-agents", "canonical_source": "https://gist.github.com/kju4q/283c3e949d00e27da0a5cc3a60439ea8", "published_at": "2026-07-31 17:09:21+00:00", "updated_at": "2026-08-01 00:00:31.255848+00:00", "lang": "en", "topics": ["ai-agents", "developer-tools", "artificial-intelligence"], "entities": ["Claude Code", "Anthropic", "ai-weekend-builds", "claude-sonnet-5"], "alternates": {"html": "https://wpnews.pro/news/three-things-already-in-your-claude-code-that-most-people-haven-t-touched-agents", "markdown": "https://wpnews.pro/news/three-things-already-in-your-claude-code-that-most-people-haven-t-touched-agents.md", "text": "https://wpnews.pro/news/three-things-already-in-your-claude-code-that-most-people-haven-t-touched-agents.txt", "jsonld": "https://wpnews.pro/news/three-things-already-in-your-claude-code-that-most-people-haven-t-touched-agents.jsonld"}}