feat(llm-security): add pre-compact-poisoning example for PreCompact hook [skip-docs]

Runnable demonstration of hooks/scripts/pre-compact-scan.mjs (the
only PreCompact hook in the plugin) detecting both a CRITICAL
injection pattern and an AWS-shaped credential inside a synthetic
JSONL transcript, exercised across all three values of
LLM_SECURITY_PRECOMPACT_MODE plus a benign-transcript control case
in block mode that proves the gate is not a brick wall.

The transcript is generated at runtime in a per-invocation tempdir
under os.tmpdir() and the directory is removed in a finally block,
so the user's real ~/.claude/projects/.../transcripts/ are never
touched. The AWS-shaped key uses the same 'AK' + 'IA' + ...
fragmentation idiom as tests/e2e/attack-chain.test.mjs so this
source contains no literal credentials and pre-edit-secrets does
not block writes during development.

Nine independent assertions (9/9 must pass):
- block mode + poisoned: exit 2, decision=block JSON, reason text
  covers both injection and AWS labels (3 assertions)
- warn mode + poisoned: exit 0, systemMessage JSON, no decision
  field (2 assertions)
- off mode + poisoned: exit 0, no JSON on stdout (2 assertions)
- block mode + benign: exit 0, no decision=block JSON (2 assertions)

OWASP / framework mapping: LLM01, LLM02, ASI01, AT-1, AT-3.

Docs updated: plugin README "Other runnable examples", plugin
CLAUDE.md "Examples" tabellen, CHANGELOG [Unreleased] Added.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Kjell Tore Guttormsen 2026-05-05 15:22:28 +02:00
commit b6d912200e
6 changed files with 525 additions and 0 deletions

View file

@ -95,6 +95,21 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
the orchestrated `scan-orchestrator.mjs` flow exercises the
`enrichFromPriorResults()` pass that this example deliberately
skips. Maps to ASI01 / ASI02 / ASI05 / LLM01 / LLM02 / LLM06.
- `examples/pre-compact-poisoning/` — runnable demonstration of
`pre-compact-scan.mjs` (the only `PreCompact` hook in the plugin)
detecting both a `CRITICAL_PATTERNS` injection phrase and an
AWS-shaped credential inside a synthetic JSONL transcript,
exercised across all three `LLM_SECURITY_PRECOMPACT_MODE` values
(off / warn / block) plus a benign-transcript control case in
block mode that proves the gate is not a brick wall. The
transcript is generated at runtime under `os.tmpdir()` and the
tempdir is deleted in a `finally` block, so the user's real
`~/.claude/projects/.../transcripts/` are never touched. The
AWS-shaped key uses the `'AK' + 'IA' + ...` fragmentation idiom
from `tests/e2e/attack-chain.test.mjs` so the source contains no
literal credentials and `pre-edit-secrets` does not block writes
during development. Nine independent assertions (9/9 must pass).
Maps to LLM01 / LLM02 / ASI01 / AT-1 / AT-3.
## [7.3.1] - 2026-05-01