Skip to content

claude-ops/plugins: cache-content-check.test.sh process-budget probe measures -1 in the Claude Code on the web container #4046

Closed

Description

@kyle-sexton

Summary

plugins/claude-ops/skills/plugins/scripts/cache-content-check.test.sh fails 2 of 26 cases in a Claude Code on the web session on this repository:

FAIL: process budget: the trace probe actually counted something
  detail: measured -1 — the pid-stamped PS4 did not reach the traced shell, so the ceiling below is vacuous (trace: /var/tmp/cache-content-check.XXXX/case-26/trace-large.log)
FAIL: process budget: a one-install report costs at most 26 process creations
  detail: measured -1 (trace: /var/tmp/cache-content-check.XXXX/case-26/trace-large.log)

The probe runs bash -x "$SCRIPT" with PS4='+${BASHPID}+ ' passed through env and counts distinct pids in the trace. The other 24 cases pass, and the checker itself reports correct verdicts. Reproduced on the unmodified origin/main tree at 9e54a75 as well as on a branch.

Root cause

Verified 2026-09-11 against primary sources and reproduced by an independent verifier in this container:

  • Bash 4.4 and later rebind an euid-0 shell's PS4 to + at startup, unconditionally, before any startup file runs (variables.c: if (current_user.euid == 0) bind_variable ("PS4", "+ ", 0);; bash CHANGES, 4.4-rc1 item g; CVE-2016-7543). The GNU bash manual does not document this discard.
  • The Claude Code on the web container runs as uid 0. In it, env PS4='+${BASHPID}+ ' bash -x -c true prints + true; the same command as uid 65534 (via setpriv) prints +<pid>+ true.
  • PS4 set after startup survives: an in-shell assignment, or a BASH_ENV file that assigns it, produces pid-stamped trace lines as root. Both were reproduced.

So the probe is at fault, not the environment: passing PS4 through the environment cannot reach a root shell on any bash since 4.4, and the repository's tests run as root in this container.

The sibling plugins/claude-ops/skills/plugins/scripts/fleet-state.test.sh (lines 2034 to 2042) runs the identical env-route probe and has no fail-closed floor: its count_creations also returns -1 here and -1 <= <ceiling> passes vacuously, so that suite is silently green in every root container. It is in scope for the same fix.

Fix

  • In both test suites, set PS4 after shell startup instead of through the environment: point BASH_ENV at a temporary file containing PS4='+${BASHPID}+ ' (single-quoted so ${BASHPID} expands per traced line), or assign it inside the traced shell before set -x. BASH_ENV reaches the script under test without sourcing it. The one unstamped + PS4=... line a BASH_ENV route adds does not match count_creations's ^\++[0-9]+\+ pattern, so it is harmless.
  • Give fleet-state.test.sh's probe the same fail-closed floor cache-content-check.test.sh already has, so a probe that counts nothing fails rather than passing every ceiling.

Acceptance criteria

  • Both suites report all cases passing in a Claude Code on the web session on this repository (uid 0) and on Linux CI.
  • IF the trace carries no pid-stamped line, THEN each suite's process-budget cases FAIL naming the probe, in both suites, never pass vacuously.
  • WHILE the traced shell runs as uid 0, the probe still measures a positive process count.
  • The process-budget ceilings themselves are unchanged: a count above the documented per-install budget still fails.

Verification

Run bash plugins/claude-ops/skills/plugins/scripts/cache-content-check.test.sh and bash plugins/claude-ops/skills/plugins/scripts/fleet-state.test.sh as root in a Claude Code on the web session (id -u prints 0) and on Linux CI; scripts/affected-tests.sh --run on the changed files.

Environment

Related

Activity

  1. added
    needs-triageNot yet classified. Floor until a type and one priority tier are set.
    on Sep 10, 2026
  2. added
    priority: highSignificant impact, or blocks an imminent release; staff this cycle.
    agent-readyFully specified and briefed; eligible for autonomous pickup from the frontier.
    work-class: scopedA briefed fix or small feature; blast radius bounded by the brief, tests exist.
    and removed
    needs-triageNot yet classified. Floor until a type and one priority tier are set.
    on Sep 11, 2026
  3. added a commit that references this issue on Sep 11, 2026
    4eadfe7
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-readyFully specified and briefed; eligible for autonomous pickup from the frontier.priority: highSignificant impact, or blocks an imminent release; staff this cycle.work-class: scopedA briefed fix or small feature; blast radius bounded by the brief, tests exist.

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions