The BLOCK rule named "Filesystem root destruction" did not block the bare
root target it is named for. The target alternation ended in a shared `\b`,
and a word boundary cannot hold after `/` or `~` at end-of-command.
Measured against the shipped pattern:
bare `/` target NOT blocked `$HOME` target blocked
bare `~` target NOT blocked `/usr` target blocked
`/*` glob target NOT blocked
swapped flags (-fr) NOT blocked
sudo-prefixed NOT blocked
Only targets whose first character is a word character ever satisfied the
assertion, so the rule caught `/etc` but not bare root. These fell through
to WARN (exit 0) — advisory only, command executed.
- Pattern: `\b` moved onto the `$HOME` alternative alone, where it is
meaningful (it ends in a word char, so `$HOMEDIR` is still not
swallowed). Dropped from `/` and `~`. Nothing else changes: `/etc`,
`/home`, `./build` behave exactly as before.
- The old test file encoded this defect as expected behaviour, with a NOTE
claiming the pattern "requires separate flag groups (e.g. -f -r, not -rf
combined)". That diagnosis was wrong — the `/etc` case blocks fine with
merged flags. Comment replaced with the real root cause.
npm test: 1872/1872 green (1865 + 7 new).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TcQyMTQfyrsAapaCMPxTtQ
Adds BLOCK_RULE for the malware-loader pattern:
echo|cat|printf <base64-blob> | base64 -d | <shell>
This is a common RCE delivery shape that bypasses static name-matching
gates by encoding the destructive command as a base64 blob. The new
rule fires only when the final pipe target is a shell interpreter
(bash, sh, zsh, dash, ksh) — base64 decoded into jq or any non-shell
consumer remains allowed.
5 new tests in pre-bash-destructive.test.mjs:
- 3 BLOCK cases (echo|base64|bash, printf|base64|sh, cat|base64|zsh)
- 2 FP probes (base64 -d -> jq passes; base64 -d alone passes)
Closes E9 in critical-review-2026-04-20.md.
New policy-loader.mjs reads .llm-security/policy.json with deep-merge against
defaults that exactly match existing hardcoded values. Integrated into all 7 hooks:
- pre-prompt-inject-scan: injection.mode (env var still takes precedence)
- post-session-guard: trifecta.mode, window_size, long_horizon_window
- pre-edit-secrets: secrets.additional_patterns
- pre-bash-destructive: destructive.additional_blocked
- pre-write-pathguard: pathguard.additional_protected
- pre-install-supply-chain: supply_chain.additional_blocked_packages
- post-mcp-verify: mcp.volume_threshold_bytes, mcp.trusted_servers
Backward compatible: no policy file = identical behavior to v5.1.0.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add /ultraresearch-local for structured research combining local codebase
analysis with external knowledge via parallel agent swarms. Produces research
briefs with triangulation, confidence ratings, and source quality assessment.
New command: /ultraresearch-local with modes --quick, --local, --external, --fg.
New agents: research-orchestrator (opus), docs-researcher, community-researcher,
security-researcher, contrarian-researcher, gemini-bridge (all sonnet).
New template: research-brief-template.md.
Integration: --research flag in /ultraplan-local accepts pre-built research
briefs (up to 3), enriches the interview and exploration phases. Planning
orchestrator cross-references brief findings during synthesis.
Design principle: Context Engineering — right information to right agent at
right time. Research briefs are structured artifacts in the pipeline:
ultraresearch → brief → ultraplan --research → plan → ultraexecute.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>