Skip to content

[audit] Sync/blocking work runs inline on the async (Tokio) runtime #6553

Description

@7jrxt42BxFZo4iAnN4CX

Source: static audit of main@384439634. Candidates are static and not reproduced — confirm each before changing code.
Template: agent-task (agent-ready, docs/ISSUE_TRIAGE.md). Labels: bug, agent-ready.

Goal / Why

Filesystem, subprocess, git, secret-store, and tempfile work is executed synchronously inside async call chains (engine tasks, tool handlers, UI event loop, runtime API). Parking a Tokio worker stalls every task sharing that runtime: the TUI stops responding to input, unrelated tools and streaming freeze, and cancellation/timeouts are delayed. Repository convention #6149 requires tokio::fs/tokio::process or spawn_blocking, and scripts/check-blocking-calls-budget.py ratchets the unprotected-site count precisely to stop this class from creeping back. Each site below must move to async IO, spawn_blocking, or a dedicated thread without raising that budget.

Confirmed static findings in this class: 9 (reassessed severity noted per line).

Scope / Plan

  1. Re-read each candidate below at the cited file:line on current main; drop anything already fixed or misread.
  2. Move each listed site to tokio async IO, spawn_blocking, or a dedicated thread; do not raise the blocking-calls budget.
  3. Add the smallest regression/gate that would catch a re-introduction (focused test, budget script, or grep guard).

Key files

  • crates/tui/src/core/engine.rs
  • crates/tui/src/core/engine/tool_execution.rs
  • crates/tui/src/tools/test_runner.rs
  • crates/tui/src/commands/contract.rs
  • crates/tui/src/client.rs
  • crates/tui/src/route_runtime.rs
  • crates/tui/src/runtime_api.rs
  • crates/tui/src/runtime_api/sessions.rs
  • crates/tui/src/runtime_chat_relay.rs
  • crates/tui/src/task_manager.rs
  • crates/tui/src/tui/git_status.rs
  • crates/tui/src/tui/worktree_manager.rs
  • crates/core/src/lib.rs
  • crates/tui/src/provider_lake.rs

Acceptance criteria

  • Every listed candidate is either fixed with a test, or downgraded with a written reason in the PR.
  • No new instance of this class is introduced (guarded by the test/budget).
  • Existing behavior for unrelated paths is unchanged.

Verification

python3 scripts/check-blocking-calls-budget.py   # count must not increase
cargo check -p codewhale-tui -p codewhale-core
cargo test  -p codewhale-tui --lib
cargo clippy --workspace --all-targets --locked -- -D warnings

Out of scope

  • Findings that belong to another systemic class or to the localized backlog.
  • Re-architecture beyond the listed sites.

Related existing work (do not duplicate)

#6149 (blocking calls in async paths), #6211 (polling/blocking shapes), #6333 (async I/O hardening), #6140 (MCP stdio async-native), #5616, #6371/#6372 (terminal routes off runtime)

Candidate findings (9)

  • C02-09 · C02 — TUI engine and turn loop · crates/tui/src/core/engine.rs:3720, crates/tui/src/core/engine.rs:7012, crates/tui/src/core/engine/tool_execution.rs:193 — sync fs/process/skill/audit/tempfile work runs inline on the Tokio runtime.
    audit severity: major; reassessed: major
  • D04-03 · D04 — Registry, tasks, workflow, verifier · crates/tui/src/tools/test_runner.rs:105 — sync Command::output() without timeout/cancel blocks the Tokio executor.
    audit severity: major; reassessed: major
  • C01-07 · C01 — TUI command contract · crates/tui/src/commands/contract.rs:2505 — production command handlers perform blocking I/O/subprocess on the async UI path.
    audit severity: major; reassessed: major
  • T02-12 · T02 — Model HTTP/SSE clients · crates/tui/src/client.rs:648, crates/tui/src/route_runtime.rs:264 — route validation/rebind sync reads secret store/cert files on a Tokio worker.
    audit severity: major; reassessed: major
  • T05-06 · T05 — Runtime API, ACP, control socket, web/mobile · crates/tui/src/runtime_api.rs:2524, crates/tui/src/runtime_api/sessions.rs:150, crates/tui/src/runtime_chat_relay.rs:730 — sync full-ledger/session/settings/atomic writes run on Tokio workers.
    audit severity: major; reassessed: major
  • T08-07 · T08 — Runtime threads, tasks, automation, goals · crates/tui/src/task_manager.rs:2946 — every async task operation sync scans the store on a Tokio worker.
    audit severity: major; reassessed: major
  • U08-08 · U08 — Setup, approvals, hotbar, session/config · crates/tui/src/tui/git_status.rs:209, crates/tui/src/tui/worktree_manager.rs:216 — worktree name/path not contained, multiple sync Git commands without timeout/cancel.
    audit severity: major; reassessed: major
  • R05-06 · R05 — Core, memory, telemetry client/ingest · crates/core/src/lib.rs:1035 — Async API sync state-store/FS inline blocks Tokio.
    audit severity: major; reassessed: major
  • T03-m2 · T03 — Models, providers, routing, pricing · crates/tui/src/provider_lake.rs:1566 — Sync cache merge/serialization/atomic write runs on a Tokio worker.
    audit severity: minor; reassessed: minor

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    needs-triageNew external report awaiting maintainer triage; repro, logs and version output help

    Projects

    • Status
      Backlog

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions