chore(release): v8.1.3 — install locations, both config dirs, case, watch cwd

Version 8.1.3 in package.json, .claude-plugin/plugin.json, README badge
and changelog list, CLAUDE.md header and highlights, CHANGELOG. No tag:
release-plugin.mjs is the operator's push round.

Also in this commit: file content no longer carries order IDs or
pointers into the local-only plan (comments and test names in the
own-working-tree, av-surface and watch-cron tests; `punkt N` -> `(N)`).
README's antivirus section now says v8.1.3 touched it.

Suite after `git add`: 2344 tests, 2338 pass, 0 fail, 6 skipped.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Kjell Tore Guttormsen 2026-09-23 11:55:08 +02:00
commit 34617305c8
Signed by: ktg
SSH key fingerprint: SHA256:JakMjO6FTBBzN0Bhfj9saOoEjaFxlSdYuZQQpM/lF9Q
9 changed files with 100 additions and 25 deletions

View file

@ -6,6 +6,78 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
## [Unreleased]
## [8.1.3] - 2026-09-23
Patch that closes most of the v8.1.2 known-open list, the `/security watch`
config gap and three findings from the README fact-check. Detection tables,
golden baseline and hooks are unchanged. Windows/Defender quarantine is still
not measured. 2344 tests, 2338 pass, 6 skipped, 0 fail.
### Fixed
- **More install locations are foreign.** A target is now also foreign when
the path from the working directory down to it has a `site-packages` folder
(a Python virtual environment) or a `vendor` folder (composer, bundler, Go)
in it, like `node_modules` since 8.1.2, and when it lies under a Claude Code
config directory's `skills/` folder, like its `plugins/` folder
(`scanners/lib/own-working-tree.mjs`).
- **Both config directories count.** The plugin and skills check covers
`~/.claude` *and* the directory `CLAUDE_CONFIG_DIR` points at, so pointing
the variable at another profile no longer makes `~/.claude/plugins` your own
tree. A leading `~` in the variable is expanded to the home directory; a
relative value is still resolved against the working directory. Anthropic's
documentation does not say whether Claude Code itself expands `~` there (not
verified), so both readings are treated as foreign.
- **Letter case no longer decides.** Paths are compared after
`realpathSync.native`, which returns the case stored on disk. On a
case-insensitive volume (macOS APFS) `NODE_MODULES/pkg` is the
`node_modules` folder it names and is foreign, and a path to your own folder
typed with different case (`/users/…` for `/Users/…`) is your own tree. The
second one was foreign before, the safe direction; it is no longer a special
case.
- **`/security watch` as a cron job honours the watched project's own
configuration.** `scanners/watch-cron.mjs` started the scan with the plugin
directory as working directory, so every watched project was foreign and its
`.llm-security-ignore` and `policy.json` were dropped: you were shown
findings you had already suppressed. The scan now runs from the project's
directory (its parent for a single file). A relative `path` in the watch
config still resolves against the plugin directory.
- **No runnable base64-to-shell line left on disk.** A comment in
`examples/bash-evasion-gallery/run-evasion-gallery.mjs`, the gallery README
and `tests/e2e/attack-chain.test.mjs` each held a complete
"decode base64 into a shell" line whose short blob decodes to a recursive
delete. The blobs are now encoded at runtime; the README shows a
placeholder. New gate probe (b2) in `tests/av-surface.test.mjs` catches the
shape at any blob length (the existing probe starts at 24 characters).
- **`docs/ci-cd-guide.md` and `docs/scanner-reference.md` no longer call the
CLI offline.** The dep scanner runs `npm audit` and `pip-audit`, the network
scanner resolves domains over DNS and the supply-chain scanner queries
OSV.dev, whenever their input is present and with no switch to turn them
off. The guides said "zero network calls", "OSV opt-in" and referred to a
`--online` flag that does not exist.
- `docs/scanner-reference.md` lists all 22 knowledge files (it said 20).
**Behaviour change:** scanning a folder under `site-packages/` or `vendor/`,
or a skill under `~/.claude/skills` (or `$CLAUDE_CONFIG_DIR/skills`), no
longer applies that folder's ignore file or policy, including a folder of
your own that happens to be named `vendor` and skills you wrote yourself.
This is the safe direction: more findings, never fewer.
### Known open
- **A `git archive` export or an unpacked tarball under the working
directory still counts as your own tree** (no marker tells it apart).
- **The working directory inside `node_modules`:** with the working directory
at `project/node_modules` and a sibling package as target, only the path
below the working directory is checked, so the package counts as your own.
Rare.
- **Exotic losses on the own side:** a target in the project's own
`.claude/plugins/…` or `.claude/skills/…` becomes foreign when `HOME` is
empty or `CLAUDE_CONFIG_DIR=.claude` (relative). A plugin placed by hand
directly under `~/.claude/plugins/` is foreign (intended).
- Kept on purpose (safe direction): a git worktree of your repository checked
out inside it, scanned from the main checkout, is foreign.
## [8.1.2] - 2026-09-22
Patch that closes both items v8.1.1 left open. Detection tables, golden