agent-approval-protoco…
Use for approval_request, COMMAND_SET, approval identifiers, fingerprints, and progress data
Use when the user wants something to run routinely / on a schedule rather than once now -- "tarea programada", "rutinariamente", "cada mañana", "cada N horas", "todas las noches", "schedule", "cron". Covers mounting, structuring, and running an unattended headless task that
$ npx -y skills add metraton/gaia --skill scheduled-task --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/scheduled-taskContext preview
The summary Claude sees to decide when to auto-load this skill.
Use when the user wants something to run routinely / on a schedule rather than once now -- "tarea programada", "rutinariamente", "cada mañana", "cada N horas", "todas las noches", "schedule", "cron". Covers mounting, structuring, and running an unattended headless task that
name: scheduled-task description: Use when the user wants something to run routinely / on a schedule rather than once now -- "tarea programada", "rutinariamente", "cada mañana", "cada N horas", "todas las noches", "schedule", "cron". Covers mounting, structuring, and running an unattended headless task that reports back, plus consuming its reports. NOT for work that runs once now in this session.
A scheduled task is a Gaia task that runs **unattended on a recurring schedule** via the OS crontab, executes `claude -p` headless, and leaves the user a report in the notifications inbox instead of asking anything mid-run. This skill covers the three flows of its lifecycle: creating one, executing it headless, and consuming what it reports. Work the user wants done once, now, in this session is an ordinary dispatch, not a scheduled task.
The load-bearing constraint that shapes everything below: a headless run has no user to answer a prompt. So a scheduled task must complete everything it can WITHOUT a T3 mutation, and when a T3 is unavoidable it must NOT try to ask -- it accumulates the `approval_id`, finishes the rest, and reports back so the user can resume and grant later. Gaia's T3 layer gates independently of Claude Code's permission dialog: `--dangerously-skip-permissions` removes the TUI prompt, but Gaia still blocks/accumulates T3 mutations exactly the same.
Trigger when the user asks for routine/scheduled execution: "cada noche corre X", "rutinariamente revisa Y", "cada 6 horas", "prográmame Z". If they want it run once now, this is the wrong skill -- that is an ordinary one-shot dispatch.
Build three artifacts, in order. Heavy mechanics and the full wrapper rationale are in `reference.md`; the runnable templates are in `scripts/`.
1. **Write the task as a read-only-first atomic prompt.** State the task's job as a self-contained prompt that opens with the headless preamble (Flow B). Front-load everything read-only; isolate any mutation as an explicit, clearly-labeled step so the headless run can skip-and-accumulate it cleanly. Store the prompt in its own file (one task = one prompt file). 2. **Copy the wrapper** `scripts/run-scheduled-task.sh` to a per-task file (e.g. `~/ws/me/scheduled-tasks/<task>.sh`) and edit its `==CONFIG==` block: `TASK_NAME`, `PROJECT_DIR`, `PROMPT_FILE`. The wrapper exports credentials and PATH **explicitly** (cron has almost no environment), runs the validated headless invocation, persists the session, and parses out the `session_id`. Do not drop `--output-format json` or add `--no-session-persistence` -- the session MUST stay resumable. 3. **Add a staggered crontab entry** from `scripts/crontab.template`. Give the wrapper an ABSOLUTE path, redirect to a per-task log, and offset the minute so no two tasks start in the same minute.
Every scheduled-task prompt begins with this preamble, verbatim in spirit:
> Eres una tarea programada headless. Nadie está mirando y no puedes preguntar > nada. Procede así: > > 1. **Intenta completar la tarea SIN ninguna mutación T3.** Haz todo el trabajo > read-only / T0-T2 que puedas. > 2. **Si hay un T3 inevitable, NO llames AskUserQuestion.** El comando se > bloqueará con un `approval_id`. NO reintentes. ACUMULA cada `approval_id` > (con el comando exacto y por qué hace falta) y sigue con TODO lo demás que > sí puedas terminar. > 3. **Captura tu `session_id`** leyendo `$CLAUDE_SESSION_ID` en la sesión > top-level (ver abajo) para poder estamparlo en el reporte. > 4. **Redacta un mensaje final GENÉRICO** (sin nombres propios ni datos > sensibles) con el formato de abajo. > 5. **Guarda ese mensaje** como último paso con `gaia notifications add` (T0).
The report must carry the run's `session_id` so the user can `claude --resume <session_id>` to grant the accumulated T3s. The headless session reads its OWN id from its shell env var -- it is NOT parsed from `--output-format json`, and NOT asked from the user:
echo $CLAUDE_SESSION_ID
**Read it at the TOP-LEVEL session, never inside a dispatched subagent.** `$CLAUDE_SESSION_ID` does not propagate to a subagent's shell, so a task that delegates its work to a subagent and reads the var there gets an empty value and the report lands with `session_id` "-". Capture the id in the main session and pass it through. If it is genuinely empty, omit `--session-id` and note in the body that the user recovers pending grants with `gaia approvals pending --all-sessions` (which does not depend on the id).
He terminado la tarea <nombre>: <qué hizo en una línea>. Aprobaciones pendientes: <lista de approval_id + por qué cada uno>, o "ninguna". session_id: <valor de $CLAUDE_SESSION_ID, o "ninguno — usa gaia approvals pending --all-sessions">.
The task's LAST action is to persist that message (substitute the value you read for `$CLAUDE_SESSION_ID`):
gaia notifications add \ --task "<nombre>" \ --headline "He terminado la tarea <nombre>: <resumen>" \ --body "<mensaje completo, incluidas las aprobaciones pendientes>" \ --session-id "$CLAUDE_SESSION_ID"
`gaia notifications add` is **T0** by design, so a headless run can always record its report without stalling on a gate. The message stays generic because a notification surfaces later out of context -- proper nouns and sensitive data do not belong in an inbox line.
The report surfaces through four escalating touchpoints; the user pulls detail on demand rather than being interrupted:
1. **Per-prompt counter** -- while there are unread reports, each prompt gets a cheap one-line `🔔 N task notifications sin ver` (nothing when N=0). 2. **SessionStart li
Repo: metraton/gaia
Use for approval_request, COMMAND_SET, approval identifiers, fingerprints, and progress data
Use for the exact input/output schema and validation rules of agent_contract_handoff
Use when creating a new specialist agent for Gaia, or reviewing whether an existing agent follows the correct structure, tone, and component inventory
Use when the orchestrator must read, reconcile, route, and present an agent_contract_handoff
Use when writing, drafting, or publishing a blog article for metraton.github.io