config-audit/scanners/lib
Kjell Tore Guttormsen c76dc537ce fix(scanners): a target path that does not exist is an error, not a grade
Surfaced by the router dogfood: quoting the placeholder stopped the shell from
swallowing it, which moved the failure down into the CLIs — and revealed that
most of them never check the target at all. Measured:

  node scanners/posture.mjs /nonexistent/path/xyz --output-file …
  exit 0
  Health: B (86/100) — Good shape — a few items to address

Nothing in that output distinguishes it from a real audit: well-formed
envelope, all 10 areas present, 16 opportunities reported. A typo'd path did
not fail — it flattered.

Exit 3 is the right code by the plugin's own contract: 0/1/2 are PASS/WARNING/
FAIL about a configuration that WAS examined, and every command template gates
on exactly that distinction, so a bad path flowed through the whole workflow as
a clean result.

This was a consistency gap, not a design question. Measured across the nine
target-taking CLIs, four already did it right with the same message and the
same exit code (manifest, token-hotspots-cli, whats-active, optimize-lens-cli);
five did not (scan-orchestrator and drift-cli exit 1, posture,
plugin-health-scanner and fix-cli exit 0). The five now share
lib/require-target-dir.mjs, which carries that exact behaviour. The four with
inline copies are left alone — consolidating them is a cleanup, not part of
this fix.

The guard is asserted over ALL nine CLIs, so a new one cannot join the wrong
half, and a third case is covered: a target that exists but is a regular file.
A valid target — including an empty directory — is explicitly unaffected.

Suite 1483 -> 1486, frozen v5.0.0 snapshots untouched.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YDAwy1ZXRpZxht1wyCeSbF
2026-08-09 21:18:18 +02:00
..
active-config-reader.mjs fix(acr): token estimator discounts block-level HTML comments (M-BUG-6) 2026-06-26 14:29:24 +02:00
active-model.mjs feat(skl,cml): --context-window auto model→window probe (v5.12 B8b) [skip-docs] 2026-06-23 22:29:12 +02:00
agent-listing-budget.mjs feat(scanner): add AGT per-agent description bloat advisory (v5.9 B1-rest) 2026-06-23 16:27:24 +02:00
backup.mjs fix(rollback): restore the backup path contract the engine and the commands disagreed on 2026-07-31 17:23:30 +02:00
baseline.mjs feat(ultraplan-local): v1.6.0 — /ultraresearch-local deep research command 2026-04-08 08:58:35 +02:00
best-practices-register.mjs feat(knowledge): best-practices register foundation — v5.7 Fase 1 Chunk 1 2026-06-20 22:37:47 +02:00
campaign-export.mjs feat(campaign): plan export + execution-by-reuse (v5.7 Fase 2 Block 4c) 2026-06-23 10:08:04 +02:00
campaign-ledger.mjs feat(campaign): machine-wide always-loaded token roll-up — pure layer (v5.9 B2a) 2026-06-23 16:57:31 +02:00
context-window.mjs feat(skl,cml): --context-window auto model→window probe (v5.12 B8b) [skip-docs] 2026-06-23 22:29:12 +02:00
diff-engine.mjs feat(ultraplan-local): v1.6.0 — /ultraresearch-local deep research command 2026-04-08 08:58:35 +02:00
file-discovery.mjs fix(acr): file-discovery skips backups/ dirs — never live config (M-BUG-8) 2026-06-26 12:23:43 +02:00
floor-exclusion.mjs feat(optimize): add --subtract, the subtraction axis, behind a deterministic floor 2026-07-31 16:24:51 +02:00
hook-additional-context.mjs feat(hooks): additionalContext injection advisory + filter-before lever (v5.10 B5) [skip-docs] 2026-06-23 20:28:33 +02:00
humanizer-data.mjs fix(acr): on-demand copy for oversized skill-body finding (M-BUG-16) 2026-06-30 13:30:22 +02:00
humanizer.mjs fix(acr): AGT findings humanize to "Wasted tokens" not "Other" (M-BUG-17) 2026-06-30 13:51:55 +02:00
knowledge-refresh.mjs fix(knowledge): freshness can no longer be green on outdated evidence 2026-08-03 11:36:57 +02:00
lens-prefilter.mjs feat(opt): optimization lens Chunk 2b — opus prose-judgment analyzer + /config-audit optimize 2026-06-21 14:01:18 +02:00
mcp-deferral.mjs feat(tokens): MCP tool-schema deferral check + CLI-over-MCP lever (v5.10 B4) 2026-06-23 19:59:14 +02:00
output.mjs feat(config-audit): cross-plugin collision scanner COL (v5 N6) [skip-docs] 2026-05-01 07:46:15 +02:00
permission-rules.mjs feat(dis): flag forbidden-param permission rules CC silently ignores 2026-06-19 14:04:25 +02:00
report-generator.mjs feat(ultraplan-local): v1.6.0 — /ultraresearch-local deep research command 2026-04-08 08:58:35 +02:00
require-target-dir.mjs fix(scanners): a target path that does not exist is an error, not a grade 2026-08-09 21:18:18 +02:00
scoring.mjs feat(scanner): add AGT agent-listing always-loaded budget finding (v5.9 B1) 2026-06-23 15:02:59 +02:00
severity.mjs feat(config-audit): export WEIGHTS from severity.mjs (v5 F3 prep) 2026-05-01 06:16:28 +02:00
skill-listing-budget.mjs feat(skl,cml): --context-window calibration, advisory when unknown (v5.11 B8) [skip-docs] 2026-06-23 21:44:52 +02:00
string-utils.mjs fix(acr): SET typo-gates unknown-key false positives (M-BUG-10) 2026-06-26 15:15:14 +02:00
subtraction-prefilter.mjs feat(optimize): add --subtract, the subtraction axis, behind a deterministic floor 2026-07-31 16:24:51 +02:00
suppression.mjs feat(ultraplan-local): v1.6.0 — /ultraresearch-local deep research command 2026-04-08 08:58:35 +02:00
tokenizer-api.mjs feat(config-audit): --accurate-tokens API calibration (v5 N5) [skip-docs] 2026-05-01 09:15:02 +02:00
write-output.mjs fix(commands): stop answering questions the caller did not ask 2026-08-01 21:26:39 +02:00
yaml-parser.mjs feat(acr,yaml): v5.6 Foundation — load-pattern enumeration + block-seq parser 2026-06-20 16:57:52 +02:00