
Blocking IO Guard
Checks async backend code for event loop blocking and keeps runtime tests in place.
Install
npx skills add bytedance/deer-flow --skill blocking-io-guard -g -a claude-code -y- Repository
- bytedance/deer-flow84.8k
- Category
- Testing
- Updated
- 3d ago
- License
- MIT
- Context cost
- Mediumabout 1,556 tokens
- Runs scripts
- Yes, review before use
What it does
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/, orbackend/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:
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:
make detect-blocking-io


