GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Crawler probes spawn gem, python and npm with no timeout, so a hung shim hangs scan forever · Issue #845 · SocketDev/socket-patch

Crawler probes spawn gem, python and npm with no timeout, so a hung shim hangs scan forever #845

New issue
Copy link
New issue
Copy link
Closed
#886
Closed
Crawler probes spawn gem, python and npm with no timeout, so a hung shim hangs scan forever#845
#886
Copy link
Labels
agent:triagedarch-auditFiled by a scheduled architecture audit routine (see the architecture review discussion)Filed by a scheduled architecture audit routine (see the architecture review discussion)bugSomething isn't workingSomething isn't workingpriority:p1

Description

@mikolalysenko
Mikola Lysenko (mikolalysenko)
opened on Oct 5, 2026
Issue body actions

[agent] Filed by the scheduled architecture audit routine (CLI and core). Register: C48.

Kind: bug. Source: new finding; register C48.

Problem

utils::process has no bounded way to run a child process. The shared probe runners, SystemCommandRunner and GlobalProbeRunner, go through run_resolved, which calls command.output() with no deadline. These probes use it:

  • gem env gemdir / gem env gempath (ruby_crawler.rs L547–L553).`` It runs on a local scan of any Bundler project, from the project fallback.
  • python3|python|py --version and the site query (python_crawler.rs L22–L34, L1608–L1619).``
  • npm root -g, the yarn, pnpm and bun global probes (npm_crawler.rs L1596–L1607), and `composer global config home` ([`composer_crawler.rs` L374](https://github.com/SocketDev/socket-patch/blob/045d7ec783d788bf3c5a1310724b51e09fb6505d/crates/socket-patch-core/src/crawlers/composer_crawler.rs#L374)).``

Every other production spawn hand-rolls its own tokio::time::timeout + kill_on_drop(true), with four different budgets:

Site Budget
pipenv --version 10 s
hatch --version 10 s
self-update sanity_exec 10 s, plus an ETXTBSY retry
git check-ignore 30 s, and 60 s at the callers

So a probe that can't answer is bounded in vendored Pipenv/Hatch and self-update, and unbounded in the crawlers that most commands run.

Proof (debug build on 045d7ec, run twice)

A Bundler project (Gemfile + Gemfile.lock naming rack 2.2.8, nothing installed) and a gem shim on PATH that never answers (exec sleep 3600, the shape of a stuck rbenv/asdf shim or a Ruby waiting on a network-mounted gem home). The API URL points at a closed local port, so a healthy run ends right after the crawl.

PATH prefix scan --json Elapsed stdout
real gem exit 1 (Connection refused), scannedPackages: 1 1 s 432 bytes
shim exiting 1 exit 1, same envelope 0 s JSON
hanging shim, run 1 killed by timeout 45 (exit 124) 45 s empty
hanging shim, run 2 killed by timeout 90 (exit 124) 90 s empty

The shim log shows that both gem env gemdir and gem env gempath were spawned and neither answered. The scan never reached the API call, and --json printed nothing, so a CI job sits until its own job timeout and reports no reason.

Symptoms

None filed. This is the process-spawn counterpart of #570 (HTTP calls had no timeout, fixed by #581).

Impact

Medium. Any wedged toolchain shim (a version manager prompting for an install, a Ruby or Python waiting on NFS, a corporate wrapper waiting on a license server) hangs scan (verified above) with no diagnostic, and by reading also the other commands that crawl through the same probes (apply, vex, rollback, get). The four per-site budgets will keep drifting, and each new probe has to remember kill_on_drop.

Proposed change

  • Add one primitive in utils/process.rs: async fn run_bounded(program: &Path, args, cwd: Option<&Path>, budget: Duration) -> ProbeOutcome. It uses tokio::process, null stdin, kill_on_drop(true), captured stdout and dropped stderr. ProbeOutcome distinguishes Ok(stdout), Failed, NotFound and TimedOut. Add one PROBE_TIMEOUT constant (10 s, matching three of the four sites), plus an env override if the contract wants one.
  • Make CommandRunner::run async, with run_resolved built on run_bounded. Callers keep their mock runners. A TimedOut probe answers "no information", as a failed one does today, and logs one --debug line naming the tool and the budget.
  • Route pipenv::installed_major, pypi_hatch::require_environment_context_support (after Fix vendored Hatch running a planted hatch (#613) #617 lands its resolve_tool change) and the npm_dir git exchange through it, with their own budgets as arguments. sanity_exec keeps its retry loop around run_bounded. Deleted: the four inline timeout + kill_on_drop blocks.

Size and scope

utils/process.rs (+80), the four timeout sites (−40), and the probe callers in the npm, ruby, python and composer crawlers. Making the trait async there is mechanical, and the ruby and python callers drop their run_blocking wrappers. Estimated ~300 changed production lines. Out of scope: what the probes ask, and resolve_tool itself.

Acceptance criteria

  • No production Command::output()/wait() remains outside utils::process (an architecture_tests grep guard, like the one PR Read NuGet and Cargo crawler project files through the FIFO-safe reader (#592) #602 adds for crawler reads).
  • Regression test (Unix): a gem shim that sleeps on PATH, with a test-only budget override; scan --json returns within the budget, scans the project, and kills the shim.
  • Unit tests for run_bounded: timeout, nonzero exit, missing program, and a child that is killed on drop.
  • The existing process.rs, pipenv, pypi_hatch, npm_dir gitignore and self-update sanity_exec tests stay green.

Dependencies

Touches vendor/pypi_hatch.rs after PR #617 (#613). Independent of the HTTP retry work (#676).

Activity

  1. Mikola Lysenko (mikolalysenko)
    added
    bugSomething isn't workingSomething isn't working
    arch-auditFiled by a scheduled architecture audit routine (see the architecture review discussion)Filed by a scheduled architecture audit routine (see the architecture review discussion)
    on Oct 5, 2026
  2. Mikola Lysenko (mikolalysenko)
    added a commit that references this issue on Oct 5, 2026

    audit-core: C11 tracking #843/#844, C48 #845 (probe deadlines)

    4284f00
  3. Mikola Lysenko (mikolalysenko)
    added
    agent:triaged
    priority:p1
    on Oct 5, 2026
  4. mikolalysenko commented on Oct 5, 2026

    @mikolalysenko
    Mikola Lysenko (mikolalysenko)
    on Oct 5, 2026
    CollaboratorAuthor
    More actions

    [agent] Triaged as priority:p1, because a hung probe blocks the gem, PyPI and npm crawlers. No duplicate or existing fix PR found. It is the process-spawn counterpart of #570/#581 (HTTP timeouts). It touches vendor/pypi_hatch.rs after PR #617 lands.


    Generated by Claude Code

  5. mikolalysenko commented on Oct 5, 2026

    @mikolalysenko
    Mikola Lysenko (mikolalysenko)
    on Oct 5, 2026
    CollaboratorAuthor
    More actions

    [agent] Claiming this issue for the architecture refactor routine (highest leverage: p1 hang fix plus one bounded spawn primitive replacing the per-site timeout blocks, without touching crawler files that open PRs edit). Branch: arch-refactor/845-bounded-probes. Claim-ID: 2026-10-05T18:56:07Z-a3f91c

    Slice 1: bound utils::process::run_resolved (every crawler probe) through one output_within primitive and route pipenv::installed_major, pypi_hatch and self-update sanity_exec through it. Remaining for a later slice: the npm_dir git exchange (open PR #837 edits that file) and the async CommandRunner trait.


    Generated by Claude Code

  6. Mikola Lysenko (mikolalysenko)
    added
    agent:claimed
    on Oct 5, 2026
  7. mikolalysenko commented on Oct 5, 2026

    @mikolalysenko
    Mikola Lysenko (mikolalysenko)
    on Oct 5, 2026
    CollaboratorAuthor
    More actions

    [agent] Draft PR: #886.


    Generated by Claude Code

  8. Mikola Lysenko (mikolalysenko)
    added 3 commits that reference this issue on Oct 5, 2026

    Bound crawler and tool probes by one deadline

    b036f7d

    refactor: #886 for #845 (C48), re-rank queue

    49b0ea0

    Bound crawler and tool probes through one spawn deadline (#845) (#886)

    6bba625
  9. Mikola Lysenko (mikolalysenko)
    closed this as completedin #886on Oct 7, 2026
  10. Mikola Lysenko (mikolalysenko)
    removed
    agent:claimed
    on Oct 7, 2026
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

    agent:triagedarch-auditFiled by a scheduled architecture audit routine (see the architecture review discussion)Filed by a scheduled architecture audit routine (see the architecture review discussion)bugSomething isn't workingSomething isn't workingpriority:p1

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      You are visitor 01402520 — GeezerVison does not store the pages you look up.
      Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.