Commit graph

325 commits

Author SHA1 Message Date
Kjell Tore Guttormsen
5cfbc70472 test(llm-security): narrative-coherence contract test (v7.1.1)
11 assertions across 4 describe groups against tests/fixtures/skill-scan/
hyperframes-like/. Tests the deterministic input layer that feeds
skill-scanner-agent — does NOT invoke the LLM (no precedent in 1511 tests).

Coverage:
- content-extractor (5 it): exit 0 on animation markup; exactly 1 HIGH
  HITL trap; >= 2 process.env credential refs; has_injection=true (any
  injection signal flips it); has_critical_injection=false (no CRITICAL
  in fixture).
- entropy scanner (2 it): calibration block present; <= 1 finding (rest
  suppressed via line-context rules).
- co-monotonicity (2 it): {high:1} → WARNING/High; {high:1, info:1} →
  WARNING (info scoring-inert). Inline guard mirrors the sweep at
  tests/lib/severity.test.mjs:252-303 so this file fails fast if the
  invariant drifts.
- agent prompt contract (2 it): static asserts that
  agents/skill-scanner-agent.md contains 'Step 2.5: Context-First
  Severity Assignment', 'summary.narrative_audit.suppressed_findings',
  'score>=65', AND zero remaining 'score >= 61' references; same v2-
  cutoff + narrative-audit contract on templates/unified-report.md.

Part of v7.1.1 narrative-coherence patch.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-29 12:50:27 +02:00
Kjell Tore Guttormsen
3abd7ffeab test(llm-security): hyperframes-like fixture for narrative coherence
Synthetic skill content mimicking the noise profile of frontend
animation projects (HTML5 canvas, framework env-vars, inline SVG data
URIs, CSS keyframes) plus exactly one genuine HITL trap signal.

Used by tests/scanners/skill-scanner-narrative.test.mjs (added in
v7.1.1) to exercise:
- content-extractor: HIGH HITL trap signal + framework env-var
  references (process.env.REACT_APP_*, VITE_PUBLIC_*)
- entropy scanner: inline SVG data URI suppressed via line-context rules

The .llm-security-ignore file uses the SCANNER:glob format
(scanners/scan-orchestrator.mjs:34-40) — ENT:**/*.md suppresses any
entropy-scanner findings when the fixture is run through scan-orchestrator
in the Step 6 smoke test.

Part of v7.1.1 narrative-coherence patch.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-29 12:49:19 +02:00
Kjell Tore Guttormsen
67ffff13a4 fix(llm-security): skill-scanner-agent — context-first severity, v2 alignment, Suppressed Signals section
Five coordinated edits to address scan-rapport whiplash at the agent
prompt level:

- Step 2.5 (NEW): Context-First Severity Assignment. Every signal has
  exactly one disposition — suppressed (counted only) or reported (full
  finding). The split happens BEFORE severity is assigned. Forbids
  'false positive', 'legitimate framework', 'no action required' in
  finding-body text; reserves them for the Suppressed Signals section.
- Verdict Logic: replaces stale v1 sum-and-cap formula (BLOCK >=61) with
  v2 reference (severity-dominated, BLOCK >=65) matching severity.mjs
  since v7.0.0. Documents that severity counts MUST exclude suppressed
  signals; introduces verdict_rationale field for descriptive context
  when suppressed >= 5 AND reported <= 1 high.
- Output Format: adds Suppressed Signals as required section #4 with
  category-level bullet format. Documents the trailing JSON shape
  including summary.narrative_audit.suppressed_findings.{count,
  by_category} and verdict_rationale fields.
- Comment block before Category 2 suppression rules clarifies that
  'false positive' as taxonomy language is OK; only finding-body
  description fields are forbidden from using the phrase.
- Step 0 (Norwegian generaliseringsgrense) preserved unchanged.

Part of v7.1.1 narrative-coherence patch (plan: .claude/plans/ultraplan-2026-04-29-report-coherence.md).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-29 12:47:58 +02:00
Kjell Tore Guttormsen
899cb5c121 fix(llm-security): template — v1 → v2 risk constants + narrative_audit block
Updates the HTML-comment risk-formula reference at lines 55-66 from the
stale v1 sum-and-cap formula to the v2 severity-dominated tiers that
have been authoritative in scanners/lib/severity.mjs since v7.0.0. Adds
a Narrative Audit block inside the Executive Summary section surfacing
summary.narrative_audit.suppressed_findings.{count,by_category} from
the agent's trailing JSON. The block is transparency only — it does
NOT affect risk_score, riskBand, or verdict.

Part of v7.1.1 narrative-coherence patch (plan: .claude/plans/ultraplan-2026-04-29-report-coherence.md).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-29 12:45:28 +02:00
Kjell Tore Guttormsen
1e555b6833 docs(llm-security): add v7.1.0 row to README version history
The v7.1.0 release commit (621db14) bumped the version badge and added a
CHANGELOG entry, but missed the README Version History table. Adding
the row now so the public-facing version history at
git.fromaitochitta.com/open/ktg-plugin-marketplace reflects v7.1.0.

Row covers: B1 + B2 + B4 fixes, A3 honesty-sweep (7 phrases), B8 CaMeL
nedton, test count 1487 → 1511, "why" framing tied to critical-review
§F CISO perspective.
2026-04-29 12:03:10 +02:00
Kjell Tore Guttormsen
621db144bd chore(release): bump llm-security to v7.1.0
Closes A4 of v7.1.0 critical-review patch — release artefacts.

- Version bump 7.0.0 → 7.1.0 across active version sources:
  * package.json
  * .claude-plugin/plugin.json
  * CLAUDE.md header
  * README.md badge
  * scanners/ide-extension-scanner.mjs (VERSION constant)
  * marketplace root README plugin entry
- Marketplace root README test count: 1487 → 1511.
- CHANGELOG.md: new [7.1.0] - 2026-04-29 section above [7.0.0],
  documenting B1, B2, B4, B8, honesty-sweep (7 phrases), and
  test-count delta (+24 → 1511 total).
- docs/security-hardening-guide.md: §6 last-updated bump + new
  v7.1.0 calibration note on hook-level fixes (pathguard regex
  hole, distributed-trifecta block-mode bypass).

Historical references to "7.0.0" intentionally preserved in:
- CHANGELOG [7.0.0] entries (history)
- README.md version-history table v5.0.0/v7.0.0 rows (history)
- CLAUDE.md §"v7.0.0 — Severity-dominated risk scoring" (describes
  what changed at v7.0.0 release)
- scanners/ JSDoc comments noting "v7.0.0+" formula provenance
- agents/ + tests/ + knowledge/ provenance comments

Pre-existing untracked/modified tracker noise (.gitignore,
marketplace.json, config-audit/docs, ultraplan-local/docs) is not
part of this commit per the v7.1.0 NEXT-SESSION-PROMPT handoff.

Tests: 1511/1511 green.
2026-04-29 11:57:16 +02:00
Kjell Tore Guttormsen
a46308b1e9 docs(llm-security): A3 honesty-sweep — 7 sitater nedtonet (critical-review §9)
Closes A3 of v7.1.0 critical-review patch. Each rewrite preserves the underlying
claim where it is accurate but removes hype/overreach language. Historical
CHANGELOG/README version-table rows are intentionally left as-is (they document
what was claimed at the time of release, not what is true today).

Changes (CLAUDE.md, commands/ide-scan.md, knowledge/mitigation-matrix.md,
docs/security-hardening-guide.md):

- "Trustworthy scoring (BREAKING)" → "Severity-dominated risk scoring
  (v2 model, BREAKING)". Removes hype framing; describes the actual mechanism.
- "Context-aware entropy scanner" → "Rule-based entropy scanner with
  file-extension skip, 8 line-level suppression rules, and configurable policy".
  No ML/context inference; just rules.
- "1487 tests" → "1511 unit and integration tests; mutation-testing coverage
  not published". Updated count after A1+A2 (+24) and added qualifier.
- "Fully Schrems II compatible" → "Schrems II compatible in default offline
  mode. Optional OSV.dev enrichment (`supply-chain-recheck --online`)
  transmits package identifiers to a Google-operated API and is a separate
  compliance consideration." Acknowledges the OSV.dev opt-in caveat.
- "Rule of Two enforcement" → "Rule of Two detection (configurable; default
  warn; blocks on high-confidence trifectas in opt-in `block` mode; distributed
  trifectas detected but not blocked by default)". "Enforcement" implied
  block; default is warn.
- "Hardened ZIP extractor" → suffix " — no fuzz-testing results published
  to date". Caps and class-of-attacks rejected are accurate; absence of
  formal fuzz coverage now stated.
- "defense-in-depth" — preserved as framing, but quantified in
  security-hardening-guide §4: "three independent detection layers with
  documented bypass classes". Each layer named, each layer's known bypasses
  pointed to (critical-review §4 evasion arsenal).

Tests: 1511/1511 green (no behavioural change).
2026-04-29 11:52:55 +02:00
Kjell Tore Guttormsen
4aa5318bcb fix(llm-security): A2 batch — JSDoc arithmetic + co-monotonicity test + CaMeL nedton
Closes A2 of v7.1.0 critical-review patch (docs/critical-review-2026-04-20.md):

- B4 (severity JSDoc): 4 critical = 93, not 90. Fixed in scanners/lib/severity.mjs:23
  and CHANGELOG.md v7.0.0 tier description. The actual computation has always been
  93 (70 + log2(5)*10 = 93.22 → round); only the docs were wrong.

- §5.4 co-monotonicity: new sweep test in tests/lib/severity.test.mjs over 15
  representative count vectors. Asserts that (verdict, riskBand) agree under the
  v7.0.0 contract for every case — catches future drift between riskScore tiers,
  verdict cutoffs, and riskBand cutoffs. Includes a B4 anchor test (riskScore
  {critical: 4} === 93) so doc/code drift fails loudly.

- B8 (CaMeL claims toned down): post-session-guard.mjs:646 comment block and
  CLAUDE.md:184 Defense Philosophy bullet now describe the implementation
  honestly — opportunistic byte-matching of truncated output fingerprints
  (first 200 bytes, SHA-256/16-hex), not semantic data-flow tracking.
  Trivially bypassed by mutation, summarisation, or re-encoding. Inspired by
  CaMeL (DeepMind 2025), but not a CaMeL capability-tracking implementation.

Tests: 1495 → 1511 (+16: 15 sweep cases + 1 B4 anchor). All green.
2026-04-29 11:49:08 +02:00
Kjell Tore Guttormsen
36be963d4d fix(llm-security): B2 block-mode blocks all detected trifectas, not only high-confidence
Previously, `LLM_SECURITY_TRIFECTA_MODE=block` only exited 2 when the
detected trifecta was MCP-concentrated (all three legs via the same MCP
server) or involved sensitive-path + exfil. Distributed trifectas —
three legs originating from different tools, with a non-sensitive data
path and a non-sensitive exfiltration sink — were detected and warned
but not blocked. This mismatched the documented semantics of block mode
and gave operators a false sense of enforcement.

Change: remove the `(mcpInfo.concentrated || sensitiveExfil)` AND-gate
in the `TRIFECTA_MODE === 'block'` branch so any detected trifecta
blocks in block mode. Audit event `severity` still differentiates
critical (concentrated / sensitive-exfil) from high (distributed); the
blocked stderr message now explicitly names "Distributed trifecta:
three legs from different sources" when the confidence sub-signals
are absent.

Addresses critical review 2026-04-20 §2 B2 (HIGH) and §9 row 1
("enforces the Rule of Two").

Tests: 1 added (distributed trifecta in block mode now exits 2).
All 1495 tests pass.
2026-04-20 00:04:36 +02:00
Kjell Tore Guttormsen
751f1199c8 fix(llm-security): B1 pathguard regex — match multi-segment .env.*.*
The previous ENV regex `/[\\/]\.env\.[a-z]+$/` only matched a single
lowercase segment after `.env`. Multi-segment and mixed-case variants
such as `.env.production.local.backup`, `.env.stage-1.local`, and
`.env.CI.secret` slipped past the hook. Replaced with
`/[\\/]\.env(\.[A-Za-z0-9._-]+)*$/` which matches `.env` plus any
number of dot-separated alphanumeric/dot/hyphen/underscore segments.
`.envrc` (direnv config, no dot separator) is still allowed.

Addresses critical review 2026-04-20 §2 B1 (HIGH).

Tests: 7 added (6 new multi-segment BLOCK cases + 1 .envrc ALLOW).
All 1494 tests pass.
2026-04-19 23:59:38 +02:00
Kjell Tore Guttormsen
a6e2c939ef docs(llm-security): add critical review 2026-04-20 (v7.0.0 adversarial audit)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-19 23:27:52 +02:00
Kjell Tore Guttormsen
0333cf1d5b docs(config-audit): straggler sweep — 7 → 8 quality areas in agent + command
feature-gap-agent and /posture command both reference quality area count.
Update both to reflect Token Efficiency as the 8th area.

Tests: 543 passing.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-19 22:58:50 +02:00
Kjell Tore Guttormsen
d2c4084ff5 docs(config-audit): update CLAUDE.md and README test count for v4.0.0
- scanner-agent + verifier-agent rows: haiku → sonnet
- Add /config-audit tokens row to commands
- Add token-hotspots.mjs row to scanners
- Add token-hotspots-cli.mjs row to action engines
- Add opus-4.7-patterns.md to knowledge base table
- Test count: 486 → 543 across 31 files (real run pass count)
- README test badge: 498+ → 543+

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-19 22:57:31 +02:00
Kjell Tore Guttormsen
1f4bbd3b52 docs(config-audit): update README for v4.0.0
- Version badge 3.1.0 → 4.0.0, scanners 8 → 9, commands 16 → 17
- New /config-audit tokens row in commands table
- TOK scanner row in deterministic scanners table
- Token Hotspots CLI in CLI tools list
- scanner-agent + verifier-agent rows updated to Sonnet
- Orchestration ASCII diagram updated (haiku → sonnet)
- v4.0.0 entry added to version history

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-19 22:55:26 +02:00
Kjell Tore Guttormsen
b9269f853d feat(graceful-handoff): initial plugin with /graceful-handoff command
New plugin that produces a complete session handoff in under 60s:
NEXT-SESSION artifact, commit+push, and copy-paste prompt for next
session. Built for context-constrained models like Opus 4.7 where
sessions fill fast.

- Single declarative command, no hooks/agents/skills
- Detects handoff type: multi-session / plugin-work / single-task
- Default filename NEXT-SESSION-PROMPT.local.md; slug-override
- Flags: --no-commit, --dry-run
- Auto-generated Conventional Commits message from git diff --stat
- Respects pre-commit hooks (secrets, pathguard) — never bypasses

Also: add *.local.md to root .gitignore (existing NEXT-SESSION files
were untracked but not ignored) and list plugin in marketplace
README + CLAUDE.md per docs-convention.
2026-04-19 22:54:10 +02:00
Kjell Tore Guttormsen
f2080adf35 docs(config-audit): add v4.0.0 CHANGELOG entry
Document the Opus 4.7 era upgrade: TOK scanner, /config-audit tokens,
Token Efficiency 8th area, scanner/verifier agent migration to sonnet.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-19 22:53:30 +02:00
Kjell Tore Guttormsen
e7bd0eba1b chore(config-audit): bump version to 4.0.0
v4.0.0 = MAJOR (Opus 4.7 era):
- New TOK scanner (Token Hotspots, 4 patterns)
- New /config-audit tokens command surface
- 8th quality area: Token Efficiency
- scanner-agent + verifier-agent migrated haiku → sonnet

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-19 22:52:28 +02:00
Kjell Tore Guttormsen
52d16d8711 docs(config-audit): refresh knowledge/ from Topic 2 Claude Code changelog research
Add 2026-04 deltas (v2.1.83-v2.1.111) verified against
research/03-claude-code-changes-config-surfaces.md (2026-04-19):
- Opus 4.7 + token-efficiency surfaces (env vars, attribution.commit/pr)
- Sandbox isolation (sandbox.* keys)
- Managed-only enterprise lockdown flags
- disableSkillShellExecution (v2.1.91)
- forceRemoteSettingsRefresh (v2.1.92)

No new hook events in this range — noted in hook-events-reference.md.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-19 22:52:11 +02:00
Kjell Tore Guttormsen
8d8e833028 refactor(config-audit): migrate scanner-agent + verifier-agent from haiku to Sonnet 4.6 2026-04-19 22:48:18 +02:00
Kjell Tore Guttormsen
97a1585dbc feat(config-audit): add /config-audit tokens command (ranked hotspots + recommendations) 2026-04-19 22:47:16 +02:00
Kjell Tore Guttormsen
cbc889f603 feat(config-audit): add token-hotspots CLI (node scanners/token-hotspots-cli.mjs) 2026-04-19 22:46:25 +02:00
Kjell Tore Guttormsen
295a6289b4 test(config-audit): extend grade-stability test to assert Token Efficiency A/B on baseline 2026-04-19 22:45:34 +02:00
Kjell Tore Guttormsen
4b385bf456 feat(config-audit): wire TOK into posture scorecard as 8th quality area (Token Efficiency) 2026-04-19 22:45:12 +02:00
Kjell Tore Guttormsen
068622e513 feat(config-audit): register TOK scanner in scan-orchestrator 2026-04-19 22:43:41 +02:00
Kjell Tore Guttormsen
a090ed3a9f feat(config-audit): add token-hotspots (TOK) scanner — Opus 4.7 pattern catalogue + ranked hotspots 2026-04-19 22:43:17 +02:00
Kjell Tore Guttormsen
712058c387 test(config-audit): add token-hotspots scanner test suite (red) 2026-04-19 22:40:44 +02:00
Kjell Tore Guttormsen
964aa29d16 docs(config-audit): add knowledge/opus-4.7-patterns.md pattern catalogue 2026-04-19 22:39:23 +02:00
Kjell Tore Guttormsen
765bc74f52 feat(llm-security): v7.0.0 commit 7 — rule 18 (markdown image URL suppression)
E2E verification against content-heavy repo (`content-claude-code`) revealed
413 entropy findings (8 HIGH / 405 MEDIUM) from markdown image CDN URLs in
JSON content indexes — e.g., `![Image 1: Title](https://www-cdn.anthropic.com/images/.../cf1dd2167fcf12f5882333ddc58a5bc1f0026952.svg)`.
These are legitimate content-repo artifacts, not credentials. The 40-char
hash segment in the CDN URL trips Shannon entropy (H=5.29 over 300 chars),
and rule 13 (inline <svg>) doesn't match since there's no literal `<svg>`
tag — the `.svg` is just a URL path suffix.

Added rule 18 `MARKDOWN_IMAGE = /!\[[^\]]*\]\(\s*https?:\/\//` — matches
`![alt](http…)` / `![alt](https…)`. Line-level (not string-level) so URL
is not over-specific.

E2E impact on `content-claude-code`:
- Before: BLOCK / 65 / 8H 437M 0L
- After:  WARNING / 56 / 3H 427M 0L

Hyperframes unchanged: BLOCK / 80 / 1C 4H 92M — real CRITICAL SQL-injection
and HIGH findings still detected.

Tests: 2 new (positive + negative fixture) bringing entropy-context to 26,
total suite 1485 → 1487.

Docs updated to "rules 11-18" and "8 new line-suppression rules".

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-19 22:37:39 +02:00
Kjell Tore Guttormsen
5a4f29fd14 test(config-audit): add marketplace-small/medium/large scanner fixtures 2026-04-19 22:36:33 +02:00
Kjell Tore Guttormsen
94ce70186c test(config-audit): add Opus 4.7 pattern fixtures (cache, redundant, imports, sonnet-era) 2026-04-19 22:34:41 +02:00
Kjell Tore Guttormsen
350cebc39c test(config-audit): add baseline-all-a fixture + grade-stability regression test 2026-04-19 22:32:40 +02:00
Kjell Tore Guttormsen
a9fb328584 fix(config-audit): complete conflict-project fixture for CNF cross-scope tests 2026-04-19 22:29:46 +02:00
Kjell Tore Guttormsen
6f86de937a feat(llm-security)!: v7.0.0 commit 6 — tests, docs, version bump
Final commit in the trustworthy-scoring series. Bundles verdict cutoff
alignment, the last suite of tests, and all documentation touch-points
that quote version numbers or describe v7.0.0 behaviour.

Verdict/band co-monotonicity
- `scanners/lib/severity.mjs` — verdict cutoffs moved from 61/21 to 65/15
  so `BLOCK >= 65`, `WARNING >= 15` locks onto the v2 riskBand() boundaries.
  Prevents "BLOCK / Medium band" contradictions under the v2 formula.

Scanner hardening (bug fixes from v7.0.0 testing)
- `scanners/entropy-scanner.mjs` — `policy_source` now uses
  `existsSync('.llm-security/policy.json')` instead of value-based check.
  Old heuristic always reported 'policy.json' because DEFAULT_POLICY now
  carries an `entropy.thresholds` section.
- `scanners/lib/file-discovery.mjs` — `.sass` and GPU shader extensions
  (`.glsl, .frag, .vert, .shader, .wgsl`) added to TEXT_EXTENSIONS. Without
  this, shader files were invisible to file-discovery, so they were never
  counted as skipped by the entropy-scanner extension filter.

Tests
- `tests/scanners/entropy-context.test.mjs` (new, 24 tests) — A. File-ext
  skip (4), B. Line-level rules 11-17 (8), C. Policy overrides (3).
  Fixtures generate 80-char base64 payloads at runtime via
  `crypto.randomBytes` to dodge the plugin's own pre-edit credential hook
  on the test source.
- `tests/lib/severity.test.mjs` — rewritten with v2 scoring table (70
  tests total, was 52).
- `tests/lib/output.test.mjs:243` — "1 critical = score 80" under v2
  (was 25 under v1).
- Full suite: 1485/1485 green (was 1461).

Docs
- `CHANGELOG.md` — v7.0.0 entry with BREAKING CHANGES section.
- `README.md` (plugin + marketplace root) — version badge, history table,
  plugin-card version string, test count.
- `CLAUDE.md` — header version, "v7.0.0 — Trustworthy scoring" summary
  paragraph at the top.
- `docs/security-hardening-guide.md` — new section 6 "Calibration & false
  positives" documenting v2 formula, context-aware entropy scanner,
  typosquat allowlist, and §6.4 tuning workflow. Existing "Recommended
  baseline" section renumbered to §7.

Version bump
- `6.6.0 -> 7.0.0` across package.json, .claude-plugin/plugin.json,
  scanners/ide-extension-scanner.mjs VERSION const, README badge,
  CLAUDE.md header, marketplace root README card.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-19 22:26:35 +02:00
Kjell Tore Guttormsen
915aca69e4 feat(llm-security): v7.0.0 commit 5 — synthesizer scan calibration section
Makes suppression stats visible in the deep-scan report so users can
audit why the scanner produced the counts it did. Before: synthesizer
would acknowledge "true risk is High, not Extreme" in prose while
verdict stayed BLOCK/Extreme — inconsistent. After Commit 1 the
orchestrator verdict is coherent on its own; synthesizer's job shrinks
to transparency.

- Adds 'Scan Calibration' section instruction consuming
  scanner.calibration.* fields (entropy files_skipped_by_extension,
  policy_source, thresholds).
- Heuristic: omit the section if < 5% of files skipped (no signal).
  Flag the section if > 80% skipped (policy may be too aggressive).
- Explicit 'Don't override verdict' directive in DON'T DO list.
  Discrepancy goes in calibration, not in a rewritten dashboard.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-19 22:04:29 +02:00
Kjell Tore Guttormsen
4c982dfb88 feat(llm-security): v7.0.0 commit 4 — typosquat allowlist for short legit names
Hyperframes scan flagged knip vs knex, oxlint vs eslint, tsx vs nx,
rimraf vs trim as HIGH typosquats. All four are legitimate top-1000 npm
packages; short names just happen to be within Levenshtein ≤2 of other
top packages. These shouldn't generate HIGH severity on a clean install.

Added to npm allowlist: knip, oxlint, tsx, nx, rimraf, glob, tar, zod,
ky, ow, esm, ip, qs, url, prettier, vitest, vite, rollup, swc, turbo,
bun, deno. Added to pypi allowlist: uv, ruff, rich, typer, anyio.

Dep-auditor normalization (lowercase + [_.-] → -) already applied at
load time. dep.test.mjs: 11/11 still green — lodsah→lodash detection
preserved.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-19 22:03:46 +02:00
Kjell Tore Guttormsen
a9e377570c feat(llm-security): v7.0.0 commit 3 — policy-driven entropy thresholds
Adds entropy section to DEFAULT_POLICY and wires it into entropy-scanner.
Users can now tune false-positive tradeoffs without forking the scanner.

Policy shape (.llm-security/policy.json):
  entropy:
    thresholds.{critical,high,medium}.{entropy,minLen}  — numeric overrides
    suppress_extensions[]                               — additive ext skip
    suppress_line_patterns[]                            — additional regex
    suppress_paths[]                                    — relPath substrings

Wiring: entropy-scanner calls loadPolicy(targetPath) at scan entry (not
orchestrator-passed — avoids signature churn across 10 scanners). Module-
level state is reset per scan invocation. Scanner envelope now includes
calibration.{policy_source, thresholds, files_skipped_by_*} for
synthesizer transparency (Commit 5).

Malformed user regex silently skipped. Missing policy.json → built-in
defaults (backwards-compatible).

entropy.test.mjs: 9/9 still green.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-19 22:02:52 +02:00
Kjell Tore Guttormsen
e7f7df0fc8 feat(llm-security)!: v7.0.0 commit 2 — context-aware entropy scanner
Observed 70% false-positive rate on renderer/shader codebases (hyperframes):
GLSL, CSS-in-JS, inline HTML/SVG, ffmpeg filter-strings, hardcoded
User-Agent strings all matched base64-like entropy thresholds. This
commit adds two suppression layers before classification.

Layer A — file-extension skip: .glsl/.frag/.vert/.shader/.wgsl (shaders),
.css/.scss/.sass/.less (stylesheets), .svg (markup), .min.js/.min.css
(minified bundles). Tracked via new calibration.files_skipped_by_extension
field on scanner envelope for synthesizer stats.

Layer B — seven new line-level suppression rules in isFalsePositive()
(rules 11-17): GLSL/WGSL keywords, CSS-in-JS (styled/emotion/@keyframes),
inline HTML/SVG markup, ffmpeg filter-graph syntax, browser User-Agent,
SQL DDL/DML, error-message templates with embedded HTML.

Existing entropy.test.mjs: 9/9 still green — known bad base64 payload in
telemetry.mjs fixture still detected. Policy-driven thresholds wired in
Commit 3.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-19 22:00:42 +02:00
Kjell Tore Guttormsen
d83424a782 feat(llm-security)!: v7.0.0 commit 1 — severity-dominated log-scaled risk score
Replace sum-and-cap formula (every non-trivial scan → 100/Extreme) with
severity-dominated, log-scaled-within-tier model. Discriminates actual
risk: 1 critical = 80, 2 critical = 86, 17 high = 65. Hyperframes-class
rendering codebases no longer collapse to Extreme just from shader noise.

Changes:
- scanners/lib/severity.mjs: new riskScore() v2; keep riskScoreV1() for
  reference; riskBand() cutoffs aligned (14/39/64/84).
- scanners/posture-scanner.mjs: delete inline duplicate formula, import
  riskScore/riskBand/verdict from severity.mjs. Single source of truth.

Breaking: aggregate.risk_score semantics change. Batched with entropy
suppression (Commit 2+) under v7.0.0 bump in Commit 6. Do not release
individually — JSON consumers depend on scoring band stability.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-19 22:00:29 +02:00
Kjell Tore Guttormsen
a86b897583 feat(ultraplan-local)!: v2.4.0 — version bump
Sync plugin.json, plugin README badge, and marketplace root README
plugin-table to 2.4.0. Closes the v2.4.0 rollout.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-19 21:46:17 +02:00
Kjell Tore Guttormsen
23544c79fb feat(ultraplan-local)!: v2.4.0 — docs update
Add v2.4.0 CHANGELOG entry documenting the background-mode removal
rationale (harness does not expose Agent tool to sub-agents per
github.com/anthropics/claude-code/issues/19077). Update plugin CLAUDE.md
architecture sections to drop background-transition phases and redefine
the three orchestrator agents as inline reference. Update plugin README
mode tables for /ultraresearch-local, /ultra-cc-architect-local,
/ultraplan-local — --fg is now a no-op alias. Update marketplace root
README with a v2.4.0 paragraph above the v2.3 changelog summary.

Closes the docs portion of the v2.4.0 rollout. Version-sync follows in
the next commit.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-19 21:39:23 +02:00
Kjell Tore Guttormsen
b5f6a528fd feat(ultraplan-local)!: v2.4.0 — correct background-agents catalog skill
Add prominent warning block that the Agent tool is not exposed to
sub-agents (foreground or background). Rewrite Shape A (orchestrator
handoff) from "valid pattern" to "confirmed anti-pattern, removed in
v2.4.0". Correct Composition section: background + subagents is
NOT supported — nested spawn from a sub-agent silently fails.

Source: github.com/anthropics/claude-code/issues/19077
Confirmed empirically 2026-04-19.

BREAKING CHANGE: Catalog consumers that cited Shape A should migrate
to orchestrating from the main command context instead.
2026-04-19 21:25:30 +02:00
Kjell Tore Guttormsen
c8a6506384 feat(ultraplan-local)!: v2.4.0 — orchestrator agents as inline reference
Redefine research-orchestrator, planning-orchestrator, and
architect-orchestrator from "background executor" to "inline
reference documentation". The agent files remain as the canonical
workflow descriptions, but the /ultra* commands now execute the
phases directly in the main command context instead of spawning
these agents as sub-agents.

The /ultra* command markdowns are now the de-facto orchestrators.
Splitting work into a separate sub-agent was incompatible with the
harness's treatment of the Agent tool (not exposed to sub-agents).

BREAKING CHANGE: These agents are no longer invoked. Any external
integration that spawned them directly should now invoke the
corresponding /ultra* command instead.
2026-04-19 21:24:45 +02:00
Kjell Tore Guttormsen
4bba65cddf feat(ultraplan-local)!: v2.4.0 — commands default to foreground
Remove background-transition phases from /ultraresearch-local,
/ultraplan-local, /ultra-cc-architect-local, /ultrabrief-local.
All four commands now run their full pipelines inline in main
context; --fg is retained as a no-op alias for backwards
compatibility.

The Claude Code harness does not expose the Agent tool to
sub-agents, so orchestrators launched with run_in_background:true
cannot spawn their documented swarms (docs-researcher,
community-researcher, architecture-mapper, plan-critic, etc.) and
silently degrade to single-context reasoning. Foreground execution
keeps the swarms intact.

Source: github.com/anthropics/claude-code/issues/19077
Confirmed empirically 2026-04-19.

BREAKING CHANGE: Default execution is foreground — the session
blocks until the brief/plan is ready. Use `claude -p` in a
separate terminal for long-running headless work.
2026-04-19 21:23:02 +02:00
Kjell Tore Guttormsen
445a632d39 docs: add AI-generated code disclosure to marketplace and all plugins
Transparency: all code in this marketplace is produced by Claude Code
through dialog-driven development. Root README gets a full disclosure
section; each plugin README gets a one-line disclosure linking back to
the marketplace section.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-19 19:27:05 +02:00
Kjell Tore Guttormsen
efbb43094f fix(ultraplan-local): v2.3.2 — skill-drafter slug-collision hint
skill-drafter now reads {catalog_root}/<slug>.md before writing its
draft and prepends a warning block to its confirmation output when
an existing skill would be overwritten during manual `mv` promotion.
The draft is still written to .drafts/<slug>.md — the check is a
hint, not a block.

Closes v2.3.0 dogfood finding (post_dogfood_findings[0]): the
drafter produced .drafts/hooks-pattern.md when an approved
hooks-pattern.md seed already existed, giving no signal that `mv`
during promotion would silently overwrite the seed. v2.3.1
introduced the qualified-slug mechanism to resolve such collisions;
v2.3.2 surfaces them at the right moment — before promotion.

Changes:
- agents/skill-drafter.md — new Step 2 between slug computation and
  source reading. Reads {catalog_root}/<slug>.md, inspects
  review_status, derives a kebab-case qualifier from the concept
  handle (or source basename fallback). Subsequent steps renumbered
  3→7. Output format gains Collision: field and optional warning
  block. New Hard Rule.
- tests/fixtures/skill-drafter/slug-collision-expected.md — reference
  fixture documenting expected confirmation shape across four
  scenarios (no collision, approved collision, soft pending
  collision, collision with no good qualifier). Skill-drafter is
  prompt-driven; fixture anchors shape for human verification and
  downstream parsers.
- CHANGELOG [2.3.2], plugin.json 2.3.1→2.3.2, README badge, plugin
  CLAUDE.md slug-convention Collision-hint bullet, marketplace root
  README summary, marketplace root CLAUDE.md plugin table.

Non-breaking. No frontmatter/drafts-layout/tool-scope/regex changes.
Existing pipelines see one extra field and an optional warning —
both purely additive.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-18 18:06:37 +02:00
Kjell Tore Guttormsen
4bbd17cbfa feat(ultraplan-local): v2.3.1 — qualified slug convention for cc-architect-catalog
Resolves v2.3.0 dogfood collision: skill-factory produced a
specialized hooks-pattern.md draft that would have overwritten the
generic seed. Qualified slugs let one feature host multiple named
patterns at different abstraction levels.

Slug convention: <cc_feature>[-<qualifier>]-<layer>.md. Unqualified =
canonical baseline. Qualified = sub-pattern (e.g., hooks-observability-
pattern.md) that does not displace the baseline.

Changes:
- SKILL.md: slug convention section, coverage-table qualified column,
  matcher logic for N patterns per feature, modification rules cover
  qualified-vs-canonical choice and collision handling.
- feature-matcher: catalog map is cc_feature -> {layer -> [skills]};
  selection rules (baseline by default, qualified when justified,
  multi-skill when non-overlapping); supporting_skill accepts list.
- gap-identifier: adds pattern_count[cc_feature] to coverage audit.
- architecture-critic: supporting-skill verification — every cited
  skill name must exist in the catalog (blocker severity).
- First qualified skill: hooks-observability-pattern.md (promoted from
  .drafts/, source ai-psychosis/README.md, ngram-overlap 0.01).
- Version bump 2.3.0 -> 2.3.1 across plugin.json, badges, table, root
  CLAUDE.md, CHANGELOG.

Non-breaking: existing unqualified slugs keep working, no cc_feature
taxonomy changes, hallucination gate unchanged.
2026-04-18 17:53:55 +02:00
Kjell Tore Guttormsen
bba72c8f06 docs(ultraplan-local): v2.3.0 — skill-factory Fase 1
Doc sync for /ultra-skill-author-local release:

- CHANGELOG.md: 2.3.0 section above 2.2.0 with full feature narrative,
  pipeline diagram, non-goals, new files list, new stats file
- README.md: command table row + new ## /ultra-skill-author-local section
  describing pipeline, modes, IP-hygiene utility, non-goals
- CLAUDE.md: row in Commands table (committed in Step 1)
- ../../README.md: bumped ultraplan-local row v2.2.0 → v2.3.0,
  expanded division-of-labor with sixth bullet for /ultra-skill-author-local,
  added v2.3 narrative paragraph

Plan: .claude/projects/2026-04-18-skill-factory-fase-1-mvp/plan.md (step 12)
2026-04-18 15:26:18 +02:00
Kjell Tore Guttormsen
6e5af6d565 feat(ultraplan-local): add /ultra-skill-author-local command
Channel 2 of skill-factory: manual one-source-at-a-time generator for
cc-architect-catalog. Validates source (.md/.txt, < 200 KB), launches
skill-author-orchestrator (opus), presents verdict summary with
context-specific next-step guidance.

Modes: default (full pipeline), --fg (alias, no-op), --quick (skip
IP-hygiene with BIG WARNING). Foreground-only in fase-1.

Plan: .claude/projects/2026-04-18-skill-factory-fase-1-mvp/plan.md (step 10)
2026-04-18 15:22:59 +02:00
Kjell Tore Guttormsen
ab8a970746 feat(ultraplan-local): add skill-author-orchestrator
Opus orchestrator for /ultra-skill-author-local. Sequential 5-phase pipeline:
validate source → concept-extractor → skill-drafter → ip-hygiene-checker
→ completion summary.

No retry logic, no parallelism, no automation (per brief Non-Goals). Each
phase consumes the previous phase's output. --quick mode skips IP-hygiene
with a BIG WARNING for testing the drafting pipeline in isolation.

Plan: .claude/projects/2026-04-18-skill-factory-fase-1-mvp/plan.md (step 9)
2026-04-18 15:21:37 +02:00
Kjell Tore Guttormsen
16e15e52bb feat(ultraplan-local): add ip-hygiene-checker agent
Sonnet worker for /ultra-skill-author-local. Runs scripts/ngram-overlap.mjs
on draft + source, parses verdict, takes action:

- accepted/needs-review: stamp ngram_overlap_score in frontmatter (Edit)
- rejected: rm draft (no preservation per brief Success Criteria 4)

Tool scope: Bash (node + rm in .drafts/), Read, Edit. Score is containment
rounded to 2 decimals to match success-criteria regex.

Plan: .claude/projects/2026-04-18-skill-factory-fase-1-mvp/plan.md (step 8)
2026-04-18 15:20:27 +02:00