Commit graph

6 commits

Author SHA1 Message Date
239e88cecb fix(acr): on-demand copy for oversized skill-body finding (M-BUG-16)
The skill-listing check emits a third finding for an oversized skill BODY
(v5.11 B7, RAW title "Skill body is large (loads on demand when the skill
runs)"). The body is an ON-DEMAND cost — it loads only when the skill is
invoked, not the always-loaded listing Claude reads every turn. The scanner is
careful to distinguish the two (RAW title + comment + evidence note).

But the humanizer-data SKL.static map had no entry for this title, so it fell
through to SKL._default ("A skill is using more of the listing budget than it
should"). The humanized title therefore claimed a listing-budget cost and
directly contradicted the finding's own humanized evidence ("loads ON DEMAND
only ... NOT every turn like the always-loaded listing") — the same internal
contradiction class as M-BUG-15/M-BUG-14, and the same "new finding type added
without a matching humanizer entry" gap the scanner checklist warns about.

Found by finding-granularity premise-verification of the linkedin-posts scan
before feeding it to the analyze pipeline (the prior session's pass focused on
the GAP findings and did not catch the SKL fall-through).

- humanizer-data.mjs: add SKL.static entry for "Skill body is large (loads on
  demand when the skill runs)" with on-demand-correct title ("A skill's body is
  large (it loads only when that skill runs)"), description, and recommendation.
  No listing-budget language; tier1/tier3 forbidden-word checks pass.
- RED-first tests at both layers: humanizer.test.mjs (humanizeFinding path:
  title is not the listing-budget _default, conveys on-demand body) and
  humanizer-data.test.mjs (static entry exists, on-demand-correct).

RAW envelope unaffected (humanizer bypassed for --raw/--json), frozen v5.0.0
snapshots untouched, default-output fixtures contain no oversized-body skill so
no snapshot regen. Suite 1357->1359/0 (+2).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01683eAqVecv9VZfQzL8CQ9h
2026-06-30 13:30:22 +02:00
2975b0563f fix(acr): honest absence-state copy for two GAP enhancement findings (M-BUG-15)
The t2_3 ("No path-scoped rules") and t3_6 ("No subagent isolation")
feature-gap checks iterate a collection (rule files / agent files) and return
false for an EMPTY one — so they fire even when the user has zero rules / zero
subagents, the same state their presence-gap siblings flag. But the humanized
titles presupposed the feature already exists:
  - "Your rules all load on every conversation" (with zero rules)
  - "Your subagents share Claude's main work folder" (with zero subagents)
The second directly contradicts GAP-005 "You haven't set up any specialized
helper agents yet" in the same report — a user cannot simultaneously have no
subagents and have subagents that lack isolation. Found by dogfooding the
analyze pipeline against linkedin-posts (premise-verifying each finding before
trusting the analyzer-agent's report).

Decided fix = align the two titles with the house "You haven't set up X yet"
absence framing (state-neutral: honest for both the zero-state and the
has-but-unconfigured state), NOT a base-feature presence gate in the scanner —
that would change the frozen v5.0.0 marketplace-medium baseline (zero
rules/agents, freezes these gaps firing) and break the RAW byte contract.
Mirrors M-BUG-14's humanizer-layer, copy-only approach.

- humanizer-data.mjs: title "Your rules all load on every conversation" ->
  "You haven't set up path-scoped rules yet"; title "Your subagents share
  Claude's main work folder" -> "You haven't set up subagent isolation yet".
  description + recommendation unchanged. t3_5/t3_7 ("Your skills don't ...")
  left as-is: their possessive is correct in the common case where skills
  exist; the zero-skills edge is latent, not manifest here.
- RED-first unit test pins both titles existence-neutral (forbids "your rules
  all load" / "your subagents"; feature still named).

Frozen v5.0.0 snapshots untouched (RAW bypasses humanizer); default-output
snapshot regenerated (2 titles only, no collateral). Verified on linkedin-posts:
GAP-004/005/011 now all consistently absence-framed. Suite 1356->1357/0.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01683eAqVecv9VZfQzL8CQ9h
2026-06-30 12:57:40 +02:00
eb0b3fd29d fix(acr): size-neutral copy for "CLAUDE.md not modular" GAP (M-BUG-14)
The t2_2 feature-gap check is a pure presence check (rules file OR @import
present) with no length gate, consistent with its t2_3/t2_4/t2_5 siblings.
But the humanized copy claimed the file is "one big block" and that splitting
makes it "easier on the loading time" — an unconditional size/load-cost
overclaim. For a ~625-token non-modular CLAUDE.md the load saving is trivial,
so the description lied. Found by dogfooding feature-gap against linkedin-posts.

Decided fix = copy-softening, NOT a length gate in t2_2 (that would make it the
only size-gated check among the presence-check siblings + risks byte-stability
if a short non-modular CLAUDE.md fixture exists in snapshots).

- humanizer-data.mjs: title "one big block" -> "all live in one file";
  description drops "long"/"loading time", keeps the honest structural
  "split into linked files with @import or .claude/rules/" framing.
  recommendation unchanged.
- RED-first unit test pins the size-neutral copy (no "big"/"long"/"loading
  time" in title/desc, structural split framing kept).

Frozen v5.0.0 snapshots untouched (RAW envelope bypasses humanizer); SC-5
default-output byte-stable (no non-modular GAP finding in those fixtures).
Suite 1355->1356/0.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01683eAqVecv9VZfQzL8CQ9h
2026-06-30 11:02:45 +02:00
e3b044a476 feat(ost): v5.6 C — output-style scanner (CA-OST, count 13→14)
New orchestrated scanner output-style-scanner.mjs — first new family since
SKL. Three findings, each pinned to a CONFIRMED V-row of the steering-model
plan + re-verified against code.claude.com/docs/en/output-styles:

- CA-OST-001 (medium, V10): user/project custom style missing
  keep-coding-instructions:true (default false) → silently strips built-in
  software-engineering instructions when active. Scoped to user/project.
- CA-OST-002 (low, V11): plugin style with force-for-plugin:true overrides the
  user's selected outputStyle. Verifiseringsplikt correction — the plan bullet
  said "project/user style," but force-for-plugin is plugin-styles-only per the
  docs, so the check keys on source==='plugin'.
- CA-OST-003 (medium): settings outputStyle matching no built-in
  (Default/Explanatory/Learning/Proactive, case-insensitive) nor discovered
  custom style → dead config.

Byte-stability — a scanner addition, not a field addition. Growing the
scanners array + scanners_ok cannot be hidden by a field strip, but re-seeding
frozen v5.0.0 (the SKL precedent) would now bake in B2's hotspot triple +
claudeMd drift. So, per the B2 lesson, frozen v5.0.0 snapshots are PRESERVED
and the OST entry is stripped at compare time via new
tests/helpers/strip-added-scanner.mjs (wired into json/raw-backcompat + the
Step 5/6 humanizer tests); only SC-5 default-output is regenerated (additive
OST entry, diff reviewed). OST is fixture-gated (no output styles on
marketplace-medium / hermetic HOME → silent).

Wiring: orchestrator; humanizer (OST→Configuration mistake) + humanizer-data
OST family (title-coupled); scoring (OST→Settings, keeps 10 areas). Suite
1012→1023 (+11). Badges: scanners 14, tests 1023, TRANSLATIONS families 15.
Lore swept: README, CLAUDE.md, scanner-internals, humanizer.md. self-audit A/A.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-20 21:02:44 +02:00
7bb254780a feat(skill-listing): add SKL scanner for the skill-listing token budget
Fase 4 Items 2+3 (CC 2.1.114→181 gap-review). New orchestrated scanner
`skill-listing-scanner.mjs` (prefix SKL) flags every active skill whose
description exceeds the verified 1,536-char listing cap (CC 2.1.105, changelog
L1502). Past the cap, Claude Code silently truncates the description the model
reads to route skill invocation — dropping the trigger phrases at the tail.
HOME-scoped over all user + plugin skills via enumerateSkills (COL is the model).

- CA-SKL-001 (medium): description > 1,536 chars. Remediation folds in Item
  2(b) — recommends disableBundledSkills + skillOverrides + trimming
  (designvalg A: no standalone GAP-check, which would fire for nearly everyone).
- Designvalg B: v1 ships the verified cap ONLY. The aggregate 2%-of-context
  listing budget is deferred — it needs a context-window assumption that would
  turn a verified fact into a guess (would carry a CALIBRATION_NOTE if added).
- Choice C: recognize the skillOverrides settings key (CC 2.1.129) in
  KNOWN_KEYS. Left OUT of TYPE_CHECKS — the value is a per-skill object
  (off/user-invocable-only/name-only), not a string; a 'string' check (as the
  plan sketched) would create a NEW false positive. Verify-first deviation.

Registration: scan-orchestrator (13th scanner), humanizer (SKL → 'Wasted
tokens' + static/_default translations), scoring SCANNER_AREA_MAP (→ Token
Efficiency; no 11th area), README badge 12→13, CLAUDE.md (finding-id +
test-count), docs/scanner-internals.md, gap-matrix + plan status notes.

Snapshots reseeded hermetically (SEED_SNAPSHOT/UPDATE_SNAPSHOT): SKL entry with
0 findings in empty HOME, scanners_ok 11→12, claudeMdEstimatedTokens bump from
the CLAUDE.md edits flowing through the cascade. Contamination grep clean.

Suite 868/868 (856 baseline + 11 SKL + 1 skillOverrides). RED→GREEN logged
per cycle.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ter3E2JSi1Khgmuf2kady8
2026-06-18 17:36:28 +02:00
Kjell Tore Guttormsen
d32166b640 feat(humanizer): translation table for 12 scanners + plugin-health
Wave 1 / Step 2 of v5.1.0 plain-language UX humanizer.

scanners/lib/humanizer-data.mjs exports TRANSLATIONS keyed by
scanner prefix (CML, SET, HKV, RUL, MCP, IMP, CNF, GAP, TOK, CPS,
DIS, COL, PLH). Each scanner has:

- static: exact-title -> {title, description, recommendation}
- patterns: array of {regex, translation} for template-literal titles
- _default: graceful fallback for unknown findings

Architectural change vs. plan: keys translations by exact scanner
title (not finding ID). Reason: finding IDs are sequence-based
(global counter in lib/output.mjs:34), not stable per finding-type
— two runs can produce different IDs for the same logical issue.
Title strings ARE stable (defined as string literals or template
patterns in the scanner source).

Translations follow research/03 SR-1..SR-17:
- active voice, second person, present tense
- sentences <= 25 words
- tier1 absolute prohibitions and tier3 domain jargon are kept out
  of prose
- tier1/tier3 terms are permitted inside `backtick spans` (code
  references like filenames and field names) — established
  technical-doc convention

Test (12 cases): all 13 scanners covered; every static and pattern
entry has the 3 required fields; tier1 and tier3 forbidden-word
checks pass (with backtick-span exclusion); reference-stable
imports. All pass.
Regression: 657/657 tests (645 + 12 new).

Project: .claude/projects/2026-05-01-config-audit-ux-redesign/
2026-05-01 17:00:59 +02:00