Skip to content

context-guard: an uninstalled plugin's tee keeps executing through the shim, plus a compounding sh -c wrap #1787

Description

@kyle-sexton

This was generated by AI while triaging findings that were stranded on merged pull requests.

Context

Two findings posted on #1252 after it merged, so the thread-resolution gate could not see them.
Found by the stranded-findings sweep; both re-verified against origin/main today by an independent
reader rather than taken from the finding text. Both are still present.

1. An uninstalled plugin's tee keeps executing through the shim (P1)

plugins/context-guard/scripts/statusline-shim.sh, in resolve_tee(): the glob

"$cache"/*/"$PLUGIN_NAME"/*/scripts/statusline-tee.sh

skips temp_* marketplace directories but never checks whether the plugin is currently
installed
. Claude Code retains an uninstalled plugin's cache entry for roughly 7–14 days, so
throughout that window the shim keeps finding and executing the removed plugin's tee, which keeps
writing snapshots.

Uninstalling a plugin should stop it running. Here it does not, and the operator has no signal that
it is still executing.

The file's own header documents why the obvious check was rejected: reading installed_plugins.json
is "an UNDOCUMENTED internal file… Revisit only if upstream documents it." That reasoning is sound
and should not simply be overridden — the fix needs a supported signal, or an explicit, recorded
decision to accept the window.

2. The unwrap instruction misses a previously-generated sh -c adapter (P2)

plugins/context-guard/skills/setup/SKILL.md, "Unwrap before you compose" (now ~line 133; it drifted
from 110 when #1603 inserted an unrelated hook-registration section). The instruction strips:

  • bash <path>/context-guard/bin/statusline-shim.sh
  • the rate-limit-guard sibling shim
  • the legacy tee prefix

It never mentions unwrapping a previously-generated sh -c '<escaped …>' adapter. On a rerun where
the renderer was wrapped in sh -c for shell syntax, the leftover sh -c '<original>' is treated as
"the renderer", still contains shell syntax, and gets wrapped in another sh -c layer. Each
setup run adds one.

Acceptance criteria

  • The shim does not execute a tee belonging to a plugin the user has uninstalled — via a
    supported signal, not the internal file the header deliberately rejected; or the window is
    consciously accepted with the reason recorded at that site.
  • A rerun of context-guard setup over an already-wrapped renderer produces exactly one sh -c
    layer, not one per run.
  • Each fix carries a regression test.
  • Both threads on feat(context-guard): version-independent statusline shim for both guard plugins #1252 are resolved once the fixes land.

Related

Refs #1252
Refs #1777

Metadata

Metadata

Assignees

Labels

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions