You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Source: PLAN Phase A1, topic plugin-audit-port — plan locked at commit 40a64b5c on feat/plugin-audit-port (read the full phase spec in the topic's PLAN.md on the task branch;
the contract slice is pruned at close-out, so cite this issue, not the path, downstream).
What to build
New context-guard plugin scaffold plus a transparent statusline tee that writes per-session
context-window snapshots. The tee wraps any existing statusline command byte-for-byte (stdout and
exit code unchanged, no tee failure may ever alter the wrapped output), and on every refresh writes captured_at + session_id + the stdin context_window object copied verbatim to ~/.claude/context-guard/context/<session_id>.json via atomic temp-file+rename with a bounded
Windows rename retry. Reuse the rate-limit-guard statusline-tee PATTERN (bounded stdin read,
jq-missing visible degrade, standalone minimal-statusline mode) — not the plugin. Sanitize session_id to [A-Za-z0-9_-] before filename use (skip the tee otherwise). Prune stale sibling
snapshots on write: never .tmp.* in-flight files, cutoff much larger than the reader contract's
staleness window (live-but-idle sessions must survive). Statusline schema was re-verified
2026-07-23 (all five Brief fields exist verbatim, plus remaining_percentage; used_percentage
and current_usage may be null early and current_usage is null right after /compact — copy
whatever is present). Re-verify the statusline doc fresh at implementation (fresh-docs mandate).
Test-first (Red-Green-Refactor) on the rate-limit-guard .test.sh harness pattern, all tests under
sandboxed HOME=$(mktemp -d). No userConfig in v1. plugin.json at version: 0.1.0.
Parent
Source: PLAN Phase A1, topic
plugin-audit-port— plan locked at commit40a64b5confeat/plugin-audit-port(read the full phase spec in the topic's PLAN.md on the task branch;the contract slice is pruned at close-out, so cite this issue, not the path, downstream).
What to build
New
context-guardplugin scaffold plus a transparent statusline tee that writes per-sessioncontext-window snapshots. The tee wraps any existing statusline command byte-for-byte (stdout and
exit code unchanged, no tee failure may ever alter the wrapped output), and on every refresh writes
captured_at+session_id+ the stdincontext_windowobject copied verbatim to~/.claude/context-guard/context/<session_id>.jsonvia atomic temp-file+rename with a boundedWindows rename retry. Reuse the
rate-limit-guardstatusline-tee PATTERN (bounded stdin read,jq-missing visible degrade, standalone minimal-statusline mode) — not the plugin. Sanitize
session_idto[A-Za-z0-9_-]before filename use (skip the tee otherwise). Prune stale siblingsnapshots on write: never
.tmp.*in-flight files, cutoff much larger than the reader contract'sstaleness window (live-but-idle sessions must survive). Statusline schema was re-verified
2026-07-23 (all five Brief fields exist verbatim, plus
remaining_percentage;used_percentageand
current_usagemay benullearly andcurrent_usageisnullright after/compact— copywhatever is present). Re-verify the statusline doc fresh at implementation (fresh-docs mandate).
Test-first (Red-Green-Refactor) on the rate-limit-guard
.test.shharness pattern, all tests undersandboxed
HOME=$(mktemp -d). NouserConfigin v1.plugin.jsonatversion: 0.1.0.Acceptance criteria
bash plugins/context-guard/scripts/statusline-tee.test.shexits 0 (sandboxed HOME; coverspass-through fidelity, snapshot shape, missing jq notice, missing
context_window,unwritable dir silent skip, pruning incl. tmp-file exclusion and idle-session survival,
session_id sanitization)
HOME=$(mktemp -d):printf '{"session_id":"t1","context_window":{"used_percentage":50}}' | bash plugins/context-guard/scripts/statusline-tee.sh catechoes the exact input bytes, exits 0, and
$HOME/.claude/context-guard/context/t1.jsonpasses
jq -e '.captured_at and .session_id and .context_window'Blocked by
None — can start immediately (lane A opener).