All skills

Runs a multi-step procedure as a Python DAG, so ordering, branching and retries are enforced by the runner rather than described in prose a model can generate past. Use for "run these steps in order and retry the flaky one until the check passes", "build a pipeline that fetches, validates, then skips the upload when nothing changed", "make sure these steps cannot be skipped", "resume from where it broke instead of redoing the expensive early stages", "run these independent calls at once and merge the results", or any procedure of 3+ steps with branches, input contracts, or side effects that must not block the critical path. Primitives are depends_on, when=, validate=, retry_until=, detached= and journal_path=. Not for a single sequential call, for steps needing reasoning between them that no predicate captures, or for async and distributed work. To audit whether one verification check can actually go red, use gating. To fan work out across many subagents, use a dynamic workflow.

Use this Skill: https://skilld.dev/gh/oaustegard/claude-skills/flowing

This session only. Nothing lands on disk.

README.md

≈1.1k tokens on demand. Your agent reads this file only when SKILL.md points to it.

flowing

A lightweight DAG workflow runner for Claude's ephemeral containers. Declare steps, wire dependencies, run once — control flow lives in code, not in prose imperatives.

The problem it solves

Multi-step procedures are usually written as prose: "first fetch X, then validate Y, then if Z retry up to 3 times, otherwise skip ahead." An LLM reads and generates past prose like that — the gate is a suggestion, not a wall. Skipped validation, retries that never happen, branches taken on stale state.

A @task graph is structural instead. A step physically cannot run until its inputs are bound to its parameters. A gate that fires on missing or bad input can't be stepped over. The runner owns branching, retrying, validating, failure propagation, and parallelism; the LLM only supplies judgment at the leaves.

from flowing import task, Flow

@task
def fetch_data():
    return {"items": [1, 2, 3]}

@task(depends_on=[fetch_data])
def process(fetch_data):          # param name matches the dep's name
    return sum(fetch_data["items"])

@task(depends_on=[process])
def store(process):
    print(f"Result: {process}")

Flow(store).run()                 # topo-sorts into layers, parallel within a layer

Control-flow primitives

The distinctive part — branches and contracts as graph structure, not if statements buried in task bodies.

Primitive What it does Use for
when= Predicate over dep values; falsy → task SKIPPED, skip cascades to dependents Branch selection in the topology
validate= Checks dep values before the body runs; raise → FAILED with no retry Enforceable input contracts between steps
retry_until= Predicate over the return value; falsy → retry, consuming the retry= budget Self-correcting LLM steps (generate → check → regenerate)

retry_until= is distinct from retry= alone: retry= only retries on a raised exception, retry_until= retries on output shape.

Also handles

  • Parallel execution — independent tasks in a layer run on a thread pool.
  • Resume — run() → fix → resume() re-runs from the failure point, keeping succeeded tasks cached. override() injects a corrected value for a step resolved out-of-band.
  • Detached side-effects — detached=True tasks (memory writes, notifications) run after the main DAG and never block it on failure.
  • timeout_s=, retry= with exponential backoff, fail_fast=.

Layout

File Audience Contents
SKILL.md Claude Trigger, mental model, quick start, the three primitives, when / when-not-to-use
references/reference.md Claude Full API — every @task parameter, Flow methods, resume/override, detached auto-discovery, signature gotchas
scripts/flowing.py — The runner itself (no third-party dependencies)
tests/test_flowing.py — 28 tests — python3 -m unittest tests.test_flowing
CHANGELOG.md — Version history

When to reach for it

Use it when a procedure has branches that matter, steps with input contracts, an LLM step that needs to converge, 3+ operations that can parallelize, or a pipeline where late failures shouldn't waste early work.

Skip it for a single sequential operation (just call the function), for a next step that needs open-ended reasoning about the prior result rather than a predicate (use a think loop), or for async / distributed workflows (this is single-container, thread-pool based).

Complements

  • orchestrating-agents — parallel API instances and delegated sub-tasks. flowing orders and gates work within one container; orchestrating-agents fans work out across many.
  • tiling-tree — MECE partitioning of a problem space. Tiling-tree decides what the branches are; flowing enforces the execution order once they exist.
  • tracking-todos — a human-legible checklist for loose, evolving work. flowing is for procedures whose shape is known up front and worth encoding as a graph.

Source: SKILL.md on GitHub

1 alert7d3 checks · Risk HIGH
  • Gen Agent Trust Hub7d

    The skill contains a high-severity security vulnerability due to the use of the unsafe 'pickle' library for its durable journaling feature. An attacker could achieve arbitrary code execution by directing the agent to use a malicious journal file. Additionally, the skill creates a surface for indirect prompt injection by using task outputs to drive agent control-flow logic.

  • Socket7d

    1 alert: gptAnomaly

  • Snyk7d

    Risk: LOW · No issues

Signed by skilld at 955c1d2. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub yesterday.

Activeupdated last month
metadata
{
  "version": "1.5.0"
}

README badge

README badge for oaustegard/claude-skills/flowing