Agent skill

Blocking IO Guard

by bytedance in bytedance/deer-flow

Adds a runtime test anchor for backend async code that could block the asyncio event loop, and proves the anchor fails when the blocking call returns.

MITAuto-check passedDevelopment

Install Blocking IO Guard

skills CLI
$ npx skills add bytedance/deer-flow --skill blocking-io-guard -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install bytedance/deer-flow blocking-io-guard --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/bytedance/deer-flow.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.agent/skills/blocking-io-guard .claude/skills/blocking-io-guard && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
blocking-io-guard
GitHub stars
84k
Token cost
~1.7k tokens
SKILL.md length
895 words
Files
4 (incl. references)
Skills in repo
23
Repo updated
First seen
Licence
MIT

At a glance

Adds a runtime test anchor for backend async code that could block the asyncio event loop, and proves the anchor fails when the blocking call returns.

  • Works in 7 steps: Scope (deterministic) → Judge each candidate (router) → Apply the fix, then re-scan (FIX+ANCHOR… → …
  • Changing backend Python that may run on the asyncio event loop
  • SKILL.md covers When to use and SOP (router)
  • Runs Python scripts from its folder; calls make, git and uv

What it does

DeerFlow's CI gate for blocking IO is a dynamic detector, which only catches blocking calls on paths a test actually runs. This skill closes the gap by pairing backend async changes with a runtime anchor under tests/blocking_io/ that is verified to fail when the blocking IO comes back. It applies to Python under backend/app, the backend harness package and backend/scripts.

In Mode A it scans your own diff against origin/main with scripts/scan_changed_blocking_io.py, run through uv, and lists candidates from added lines plus findings that are new since the merge base; work must be committed first. It notes a blind spot: a new async caller of a sync helper defined in another file is invisible, so that helper needs a manual check. Mode B runs make detect-blocking-io over the whole repo and writes findings to .deer-flow/blocking-io-findings.json.

Triage works high priority first, with one root cause per pull request while any HIGH remains, then medium and low items in batches of about five. Each candidate is routed, an anchor is drafted or extended from templates/anchor.template.py, and references/good-anchor-rules.md should be read before writing one.

When your agent uses it

  • Changing backend Python that may run on the asyncio event loop
  • Running a repo-wide triage of blocking IO findings
  • Answering a reviewer or CI request for blocking-IO coverage

Example prompts

  • “I changed the upload handler in backend/app. Check it for blocking IO and add an anchor.”
  • “Run a full blocking-IO triage round and start with the HIGH findings.”
  • “CI says blocking-IO coverage is missing for my PR. Fix it.”

Requirements

  • A DeerFlow checkout with the backend project and uv
  • The make detect-blocking-io target for full-repo scans

Workflow steps

7 steps, taken from the step headings in SKILL.md.

  1. Scope (deterministic)
  2. Judge each candidate (router)
  3. Apply the fix, then re-scan (FIX+ANCHOR only)
  4. Check existing anchors
  5. Generate / extend the anchor
  6. Verify teeth (mandatory; also the anchor-vs-rule discriminator)
  7. Deliver

What it can do on your machine

Read from SKILL.md and the folder at commit 5ecc1c2. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Ships script files (Python), which the agent can run.

    Shell commands in SKILL.md call:

    • make
    • git
    • uv

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md. Its commands use git and uv, which can reach the network depending on how they are called.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Blocking IO Guard loads about 1.7k tokens when it runs, and up to ~2.9k if it reads all its reference files. Until then it costs about 129 tokens; SKILL.md has 895 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~129
When it runs · the whole SKILL.md, loaded when a task matches
~1.7k
With references · SKILL.md plus every file in references/, read only if the agent opens them
~2.9k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from bytedance/deer-flow at commit 5ecc1c2, republished under its MIT licence (© bytedance). 895 words, ~1,693 tokens.

Download SKILL.mdSave it as .claude/skills/blocking-io-guard/SKILL.md (or your agent's skills folder). This skill also uses 3 other files; get the full folder from GitHub.
name
blocking-io-guard
description
Ensure async-path backend code that could block the asyncio event loop is protected by a teeth-verified runtime anchor in tests/blocking_io/. Use when changing backend Python under app/, packages/harness/deerflow/, or scripts/, when running a blocking-IO triage round over the whole repo, or when a reviewer/CI asks for blocking-IO coverage. Runs a deterministic scan (changed-lines or full-repo), routes each candidate, drafts/extends an anchor, and proves it fails when the blocking IO regresses.

Blocking-IO Guard Skill

Help a contributor ship backend async changes together with the runtime anchor that lets DeerFlow's blocking-IO CI gate actually see the new code. The dynamic detector only catches blocking IO on paths a test executes — this skill closes that gap, either for your own diff or for a repo-wide triage round.

Read references/good-anchor-rules.md before writing any anchor. Only read references/sop-skeleton.md when generalizing this SOP to another detector domain — it is not needed to execute the steps below.

When to use

  • Your change touches Python under backend/app/, backend/packages/harness/deerflow/, or backend/scripts/ and may run on the async event loop (Mode A). If unsure, run Step 0 — it answers deterministically.
  • You are doing a maintenance triage round over the existing codebase (Mode B).

SOP (router)

Step 0 — Scope (deterministic)

Mode A — your own diff (default, pre-PR). From repo root:

bash
uv run --project backend python scripts/scan_changed_blocking_io.py --base origin/main

Lists blocking-IO candidates your change introduces: findings on lines the diff added, plus findings that are new versus the merge base — the latter catches a new async caller exposing an old sync helper whose blocking line is not in the diff. The diff is <base>...HEAD, so commit your work first — uncommitted lines are not selected.

If the list is empty, this change introduces no blocking-IO surface that the static detector can see in the changed files. One residual blind spot remains: reachability is same-file only, so a new async caller of a sync helper defined in another file is invisible to both selections. If your diff adds an async call into a helper that lives elsewhere, check that helper manually (codegraph or git grep) before stopping.

Mode B — full-repo triage round. From repo root:

bash
make detect-blocking-io

Prints a summary and writes the complete structured finding list to .deer-flow/blocking-io-findings.json. Work HIGH priority first; do not start MEDIUM until every HIGH is dispositioned (fixed, guarded, or recorded NO-ACTION).

Batching policy (PR sizing). One fix unit per PR while any HIGH remains: a fix unit is one root cause — usually a single HIGH, but two HIGHs resolved by the same one-place fix belong together. Once no HIGH remains, MEDIUM/LOW may be batched (about five per round, grouped by module or by disposition) so each PR stays reviewable. A new Blockbuster rule is never batched with anything — it always ships alone (see Step 5).

Both modes emit the same JSON shape per finding: priority, location (path/line/function), blocking_call (category/operation/symbol), event_loop_exposure, reason, code. Priority is a deterministic review ordering, not proof of a bug — Step 1 makes the actual call.

Step 1 — Judge each candidate (router)

Read the code around each candidate and route it:

  • Already offloaded (asyncio.to_thread, run_in_executor, async client) → GUARD: add/extend an anchor that locks the offload so a future edit cannot move it back onto the loop.
  • On the loop, not offloaded → FIX+ANCHOR: offload the production code (your fix), then add an anchor that guards it.
  • Not actually exposed / acceptable (rare: scanner false positive, startup-only code) → NO-ACTION: record one line of why.
  • Cross-file caveat: the scanner's async reachability is same-file only (ASYNC_REACHABLE_SAME_FILE). If the candidate is a sync helper, check for async callers in other files (codegraph or git grep) before deciding NO-ACTION.
Show full SKILL.md (378 more words)Show less
Step 2 — Apply the fix, then re-scan (FIX+ANCHOR only)

Offload the blocking call in production code, then re-run the Step 0 scan and confirm the candidate no longer appears. If the offloaded call sits in a finally / cleanup path, keep it best-effort and bounded (swallow-and-log, asyncio.wait_for) so a failing or hung cleanup cannot mask the primary exception. Match by the stable key (path, function, symbol) — line numbers shift after edits, so never compare by line.

  • The finding must disappear. If it still shows, the fix did not remove the blocking pattern (e.g. the call is still a direct call, not offloaded) — go back before touching any test.
  • GUARD / NO-ACTION routes skip this step: a residual finding there is expected (the raw call still exists inside a sync helper with the offload at the caller, or the exposure was judged acceptable).

This is pattern-level feedback in seconds; it complements but never replaces Step 5 — only the runtime gate proves the event loop is actually protected.

Step 3 — Check existing anchors

Look in backend/tests/blocking_io/ for a test that drives the production async entry point reaching this candidate's branch.

  • Covers this branch already → go to Step 5 (re-verify teeth).
  • Covers the entry point but not this branch (e.g. happy path covered, cleanup/404/409 not) → extend that anchor.
  • None → create one from templates/anchor.template.py.
Step 4 — Generate / extend the anchor

Follow references/good-anchor-rules.md. Drive the specific branch (e.g. force the create failure that hits the cleanup shutil.rmtree). Never bypass the blocking surface with a test-only asyncio.to_thread wrapper.

Step 5 — Verify teeth (mandatory; also the anchor-vs-rule discriminator)
  1. Reintroduce the block (GUARD: temporarily revert the offload; FIX+ANCHOR: run against the pre-fix code).
  2. Run cd backend && make test-blocking-io (or target the one test). It must go RED.
  3. Restore the fix. It must go GREEN.

A real block that stays GREEN means Blockbuster has no rule for that primitive — that is the RULE route; see references/good-anchor-rules.md for the admission criteria before adding one.

Step 6 — Deliver

Commit the anchor(s) with your change; make test-blocking-io green. In the PR, note: candidates found, each disposition, the re-scan result (Step 2), and the teeth evidence (red→green). Include the reason for any NO-ACTION. A new Blockbuster rule, if any, goes in its own commit with the evidence from Step 5.

© bytedance, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

SKILL.md and 3 other files (references) in .agent/skills/blocking-io-guard of bytedance/deer-flow.

  • SKILL.md
  • references/good-anchor-rules.md
  • references/sop-skeleton.md
  • templates/anchor.template.py

Open the folder on GitHubat commit 5ecc1c2

Compare with similar skills

Blocking IO Guard next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Blocking IO Guard compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Blocking IO Guard this skillbytedance/deer-flow84k—~1.7kAutomated safety check: PassMIT
Python ProJeffallan/claude-skills12k—~1.6kAutomated safety check: PassMIT
Checkav1155/houndarr292—~366Automated safety check: PassAGPL-3.0
Pump Testingnirholas/pump-fun-sdk133—~706Automated safety check: PassCustom licence
Kedro Babysitkedro-org/kedro11k—~4kAutomated safety check: PassCustom licence
Adk Setupgoogle/adk-python22k—~993Automated safety check: NotesApache-2.0

Similar skills

  • Python Pro

    Jeffallan/claude-skills

    Writes type-annotated Python 3.11+ with async patterns, dataclasses and pytest suites, validated with mypy in strict mode, black and ruff.

    12k GitHub stars~1.6k tokensUpdated 5 days ago
    DevelopmentAuto-check passed
  • Check

    av1155/houndarr

    Run Houndarr's full quality gate (ruff lint, ruff format check, mypy, bandit, pytest) and report results in a single table.

    292 GitHub stars~366 tokensUpdated 3 days ago
    Testing & QAAuto-check passed
  • Pump Testing

    nirholas/pump-fun-sdk

    Multi-language test infrastructure for the Pump SDK — Rust unit/integration/security/performance tests, TypeScript Jest tests, Python fuzz tests, shell test orchestration, Criterion benchmarks, and…

    133 GitHub stars~706 tokensUpdated today
    Testing & QAAuto-check passed
  • Kedro Babysit

    kedro-org/kedro

    Run Kedro's local lint / format / type-check / tests on changed files (uses the project's pre-commit hooks, ruff, mypy, pytest, lint-imports, detect-secrets, Make targets — in the right venv), or…

    11k GitHub stars~4k tokensUpdated today
    DevelopmentAuto-check passed
  • Adk Setup

    google/adk-python

    Official

    Sets up a local ADK Python development environment in a git clone of the open-source adk-python repository: a uv virtual environment, all dependency extras, pre-commit hooks, and a first unit-test…

    22k GitHub stars~993 tokensUpdated today
    DevelopmentAuto-check: notes
  • Adds a release eval scorecard to a GAIA hub agent by writing a harness adapter, running a real eval, and wiring the result into the agent's README and release gate.

    1.6k GitHub stars~2.6k tokensUpdated today
    DevelopmentAuto-check passed

More from bytedance/deer-flow

All 23 skills in this repo
  • Vercel Deploy

    bytedance/deer-flow

    Deploys a project to Vercel with one script and no login, then returns a live preview URL and a claim link for moving the deployment into your own Vercel account.

    84k GitHub starsUsed in 10 repos~797 tokens
    Auto-check passed
  • Chart Visualization

    bytedance/deer-flow

    Picks a suitable chart type from 26 options for your data, maps the data to that chart's parameters and generates a chart image through a JavaScript script.

    84k GitHub starsUsed in 2 repos~840 tokens
    Auto-check passed
  • GitHub Deep Research

    bytedance/deer-flow

    Researches a GitHub repository over four rounds using the GitHub API and web search, then writes a structured markdown report with timeline, metrics and Mermaid diagrams.

    84k GitHub starsUsed in 4 repos~1.3k tokens
    Auto-check passed
  • Excel and CSV Data Analysis

    bytedance/deer-flow

    Analyzes uploaded Excel and CSV files with SQL through DuckDB, producing schema inspections, statistical summaries and exports to CSV, JSON or Markdown.

    84k GitHub starsUsed in 4 repos~2.2k tokens
    Auto-check passed
  • Structured Image Generation

    bytedance/deer-flow

    Turns an image request into a structured JSON prompt and runs a bundled Python script to generate the picture, optionally guided by reference images.

    84k GitHub starsUsed in 4 repos~2.9k tokens
    Auto-check passed
  • DeerFlow Smoke Test

    bytedance/deer-flow

    Walks through an end-to-end smoke test of a DeerFlow deployment: pull the latest code, deploy with Docker or locally, verify services, run health checks and write a report.

    84k GitHub stars~2.5k tokensUpdated today
    Auto-check: notes

Works with

Questions about Blocking IO Guard

What does Blocking IO Guard do?

Adds a runtime test anchor for backend async code that could block the asyncio event loop, and proves the anchor fails when the blocking call returns. DeerFlow's CI gate for blocking IO is a dynamic detector, which only catches blocking calls on paths a test actually runs. This skill closes the gap by pairing backend async changes with a runtime anchor under tests/blocking_io/ that is verified to fail when the blocking IO comes back.

When should I use Blocking IO Guard?

Blocking IO Guard fits situations like: changing backend Python that may run on the asyncio event loop; running a repo-wide triage of blocking IO findings; answering a reviewer or CI request for blocking-IO coverage.

How do I install Blocking IO Guard in Claude Code?

Run `npx skills add bytedance/deer-flow --skill blocking-io-guard -a claude-code`. Or copy the skill folder (.agent/skills/blocking-io-guard in bytedance/deer-flow) into .claude/skills/blocking-io-guard in your project. Claude Code loads it when a task matches its description.

How do I install Blocking IO Guard in Codex?

Run `npx skills add bytedance/deer-flow --skill blocking-io-guard -a codex`. Or copy the skill folder (.agent/skills/blocking-io-guard in bytedance/deer-flow) into .agents/skills/blocking-io-guard in your project. Codex loads it when a task matches its description.

Can I use Blocking IO Guard in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add bytedance/deer-flow --skill blocking-io-guard -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/blocking-io-guard, .gemini/skills/blocking-io-guard, .github/skills/blocking-io-guard and .opencode/skills/blocking-io-guard in your project.

What does Blocking IO Guard need to run?

Going by SKILL.md and its folder, Blocking IO Guard needs Python for the scripts in its folder and the command-line tools its instructions call (make, git and uv). Our summary lists: A DeerFlow checkout with the backend project and uv; The make detect-blocking-io target for full-repo scans.

Does Blocking IO Guard access the network?

SKILL.md contains no URLs. Its commands use git and uv, which can reach the network depending on how they are called. This is read from the text; nothing was executed.

Is Blocking IO Guard safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Blocking IO Guard use?

Blocking IO Guard is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Blocking IO Guard use?

About 1.7k tokens (SKILL.md is roughly 6.8k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full. Its references folder adds about 1.2k tokens, read only when the agent opens those files.

What are the alternatives to Blocking IO Guard?

Skills that share tags, products or a category with Blocking IO Guard: Python Pro (Jeffallan/claude-skills, 12k stars), Check (av1155/houndarr, 292 stars), Pump Testing (nirholas/pump-fun-sdk, 133 stars) and Kedro Babysit (kedro-org/kedro, 11k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Blocking IO Guard?

bytedance (a GitHub organization) maintains it in bytedance/deer-flow, which has 83,561 GitHub stars. The repository holds 23 skills in this directory. The repository was last updated on October 9, 2026.

Source: bytedance/deer-flow on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.