Skip to content
Back to skills

Run Job

ASecurity

Use this skill when the user wants to execute a planned Retriever processing run inline or in the background — including natural-language phrasings like "run OCR", "start the image-description job", "kick off the OCR worker", "process the queue", "execute run 42", "resume the stalled run", or "finish processing". It decides between inline execution and spawning a subagent, and drives the claim / complete / heartbeat loop against the processing DB.

  • 25 stars
  • 0 votes
  • 1 copy
  • 3 views
  • Added June 8, 2026
toolspythongobash

Works with

  • claude code
  • cli

Security analysis

A100/100

Scanned June 8, 2026

npx -y skills add sdemyanov/retriever --skill run-job --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Run Job?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Run Job
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/sdemyanov-run-job/badge)](https://www.skillsdirectory.com/skills/sdemyanov-run-job)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: run-job
description: >
  Use this skill when the user wants to execute a planned Retriever processing run
  inline or in the background — including natural-language phrasings like "run OCR",
  "start the image-description job", "kick off the OCR worker", "process the queue",
  "execute run 42", "resume the stalled run", or "finish processing". It decides
  between inline execution and spawning a subagent, and drives the
  claim / complete / heartbeat loop against the processing DB.
metadata:
  version: "1.1.17"
---

> Operates under `retriever:routing`. If the user's intent actually fits a different tier — another `retriever:*` skill, a Tier 2 slash, a Tier 3 `tools.py` subcommand, or (last resort) direct DB access — stop and re-route against the ladder before continuing.

# Run Job

Use this skill when the user wants to execute a planned Retriever processing run inline or in the background.

## Purpose

The processing DB is the source of truth. This skill decides whether to:

- run the work inline in the current conversation, or
- spawn a subagent for background execution

The Python CLI does not own a `--background` flag.

## Inputs

Expected user inputs:

- a `run_id`, or enough context to identify one
- optional preference to run inline or in the background

## Decision Rule

- Start with `run-status --budget-seconds 35`.
- Use `run.worker.recommended_execution_mode` as the default:
  - `inline` means stay in the current conversation
  - `background` means spawn a subagent unless the user explicitly wants inline execution
- Prefer a subagent when:
  - the user explicitly asks for background execution
  - or `run.worker.recommended_execution_mode` is `background`

When unsure, inspect `run-status --budget-seconds 35` first.

For long unattended runs, use the supervision hints from `run-status`:

- `run.supervision.should_schedule_wakeup`
- `run.supervision.wake_interval_seconds`
- `run.supervision.suggested_worker_count`
- `run.supervision.spawn_additional_worker_count`
- `run.supervision.max_parallel_workers`

If `should_schedule_wakeup` is true, keep a thread wake alive on the suggested interval (currently 60 seconds). Stop scheduling wakes when it becomes false.

## Unattended Continuation

For unattended long runs, use a thread heartbeat automation attached to the current conversation.

When to create or update it:

- the user explicitly asks to run in the background or keep going unattended
- `run.supervision.should_schedule_wakeup` is true
- the run still has pending work, active workers, or pending OCR / image-description finalization

How to configure it:

- create or update a thread heartbeat on this thread
- use the interval from `run.supervision.wake_interval_seconds`
- default cadence is once per minute
- keep the prompt short and durable:
  - resume Retriever run `<run_id>`
  - inspect `run-status`
  - if work remains, continue orchestration using this skill
  - if the run is done or canceled, stop the heartbeat and report a short summary

When to stop it:

- `run.supervision.should_schedule_wakeup` is false
- the run status is `completed`, `failed`, or `canceled`
- there are no pending/running items and no pending finalization actions

Do not build a second supervisor inside Python. The heartbeat is the wake mechanism; the skill remains the orchestrator.

## Bounded Claude Code Execution

Claude Code command calls may be interrupted around 45 seconds. Prefer the
bounded facade:

```bash
python3 skills/tool-template/tools.py run-job-step <workspace> --run-id <RUN_ID> --budget-seconds 35
```

`run-job-step` performs exactly one safe orchestration step:

- it finalizes OCR/image-description runs when the run is ready for finalization
- otherwise it claims one prepared batch and returns the item contexts for the agent/provider to process
- it uses the default stale-claim window, so abandoned inline claims can be picked up by another call after roughly 45 seconds
- it returns `next_recommended_commands` for the next bounded action

If the result contains a non-empty `batch`, process those items and call `complete-run-item` or `fail-run-item` for each one. Then call `run-job-step` again if the run still needs work.

## Execution Loop

Whether running inline or in a subagent, use the same small-batch loop.

The low-level orchestration command is:

1. `prepare-run-batch --run-id ... --claimed-by ... --budget-seconds 35 --launch-mode ... [--worker-task-id ...] [--max-batches ...] [--limit ...]`

It returns:

- current `run` status
- `worker` hints
- a claimed `batch` of run items with their execution contexts already loaded

Read `worker.next_action`:

- `process_batch`: work the returned batch
- `finalize_ocr`: call `finalize-ocr-run`
- `finalize_image_description`: call `finalize-image-description-run`
- `handoff`: stop this worker cleanly and let a fresh inline step or subagent continue
- `stop`: stop the worker loop cleanly

If `worker.stop_reason` is `canceled`, exit immediately.

## Batch Processing

For each item in `batch`:

1. Read `batch[i].context.execution.task_prompt`
2. Use the provided input payload to perform the capability work in-turn
3. Use `batch[i].context.execution.completion_template` as the exact shape for completion
4. Call `complete-run-item ...` or `fail-run-item ...`

Use these supporting commands during the loop:

- `heartbeat-run-items --run-id ... --claimed-by ...` between long batches
- `finish-run-worker --run-id ... --claimed-by ... --worker-status ...` before the worker exits
- `run-status --run-id ... --budget-seconds 35` whenever you need an external progress check
- `finalize-ocr-run --run-id ...` when `worker.next_action` says `finalize_ocr`
- `finalize-image-description-run --run-id ...` when `worker.next_action` says `finalize_image_description`

Use small batches only. The worker hints expose:

- `worker.recommended_batch_size`
- `worker.recommended_max_batches_per_worker`
- `worker.after_batch_action`
- `worker.should_exit_after_batch`

## Cancellation

- `prepare-run-batch` already reflects cancellation in `worker.next_action` / `worker.stop_reason`.
- Between batches, if `worker.stop_reason` becomes `canceled`, stop claiming work and exit cleanly.
- If a user explicitly requests force cancel, use `cancel-run --force` and inspect the returned `force_stop_task_ids`.

## Background Mode

In background mode:

- spawn a subagent
- give it the `run_id`
- give it a stable `claimed_by` worker id
- pass the subagent task id as `--worker-task-id` when available
- tell it to call `prepare-run-batch` in a loop
- tell it to process at most `worker.recommended_max_batches_per_worker` batches before returning
- tell it to write results through the retriever CLI/tool commands
- tell it to call `finish-run-worker --worker-status completed|stopped|failed` before it exits
- tell it to return only a short summary:
  - processed count
  - failed count
  - whether OCR finalization was performed
  - whether image-description finalization was performed
  - final run status

The main conversation should use `run-status` to inspect progress. Do not stream per-document OCR or extraction output back into chat.

Use a few durable workers, not one subagent per document.

- Let `run.supervision.spawn_additional_worker_count` guide how many extra subagents to start on a wake.
- Never exceed `run.supervision.max_parallel_workers`.
- A good pattern is to keep 1-4 workers alive for large queues, let each worker process up to its batch cap, then wake again and top the pool back up if needed.
- If the runtime exposes no native progress indicator, keep progress DB-backed and send only short completion / failure summaries in-thread.

On each wake:

1. Start with `run-status`.
2. If `run.supervision.should_schedule_wakeup` is false:
   - stop/delete the heartbeat
   - report final status if useful
   - do not spawn new workers
3. If `run.supervision.recommended_action` is `finalize_ocr` or `finalize_image_description`:
   - perform that finalization first
   - then re-check `run-status`
4. If `run.supervision.recommended_action` is `spawn_background_worker`:
   - spawn up to `run.supervision.spawn_additional_worker_count` subagents
   - never exceed `run.supervision.max_parallel_workers`
   - each worker gets:
     - the same `run_id`
     - a stable unique `claimed_by`
     - `launch_mode=background`
     - its own task id when available
     - the recommended batch cap
5. If `run.supervision.recommended_action` is `wait`:
   - leave existing workers alone
   - keep the heartbeat alive
6. If `run.supervision.recommended_action` is `stop`:
   - do not spawn workers
   - stop/delete the heartbeat

The agent may choose the exact worker count dynamically, but it must stay within the runtime bounds from `run.supervision`.

If `prepare-run-batch` returns `next_action = handoff`, stop this worker with `finish-run-worker --worker-status stopped` and let a fresh subagent continue from the DB state.

## Inline Mode

In inline mode:

- stay in the current conversation
- process one `run-job-step` batch at a time
- if the run remains active after one batch, continue with `next_recommended_commands`
- if the run is large enough to become noisy, switch to background mode on the next batch boundary
- if you intentionally stop at a batch boundary, call `finish-run-worker --worker-status stopped`

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.