Skip to content

Chameleon

v3.0.2 Bugfix

This release fixes issues for SREs watching stability and regressions.

✓ No known CVEs patched
Read the diff → Tool health → What is this tool? →

✓ No known CVEs patched in this version

Topics

ai-coding-assistant archetype ast-analysis claude-code claude-plugin code-conventions
+12 more
code-review code-style developer-tools javascript linter mcp mcp-server prompt-engineering python ruby rails typescript

Affected surfaces

auth rbac rce_ssrf breaking_upgrade

ReleasePort's take

Moderate signal
editorial:auto 13d

Version v3.0.2 of Chameleon introduces critical security hardening and several bug fixes across its codebase.

Why it matters: Security facts with severity ≥85 (ids 61708, 61709, 61715) block bypasses and terminal‑escape injection; operators should upgrade immediately to mitigate high‑severity risks.

Summary

AI summary

Updates P1, Known remaining, and secret across a mixed release.

Changes in this release

Security Critical

Adds decoding of hex/unicode-escaped secrets to prevent bypass of deny list.

Adds decoding of hex/unicode-escaped secrets to prevent bypass of deny list.

Source: llm_adapter@2026-07-13

Confidence: high

Security High

Arms rsync, scp, dd, and interpreter one-liners to block secret laundering past Stop backstop.

Arms rsync, scp, dd, and interpreter one-liners to block secret laundering past Stop backstop.

Source: llm_adapter@2026-07-13

Confidence: high

Security High

Prevents security‑idiom prose from silently disabling all taught idioms.

Prevents security‑idiom prose from silently disabling all taught idioms.

Source: llm_adapter@2026-07-13

Confidence: high

Security High

Sanitizes trust field in statusline to prevent terminal escape injection.

Sanitizes trust field in statusline to prevent terminal escape injection.

Source: llm_adapter@2026-07-13

Confidence: high

Bugfix Medium

Fixes per-file clock jitter causing canonical-witness recency tiebreaks.

Fixes per-file clock jitter causing canonical-witness recency tiebreaks.

Source: llm_adapter@2026-07-13

Confidence: high

Bugfix Medium

Records Bash-written no-archetype files and Bash rm operations for cross‑file existence checks.

Records Bash-written no-archetype files and Bash rm operations for cross‑file existence checks.

Source: llm_adapter@2026-07-13

Confidence: high

Bugfix Medium

Ascends through React forwardRef/memo wrappers to correctly resolve component names in TS comprehension tools.

Ascends through React forwardRef/memo wrappers to correctly resolve component names in TS comprehension tools.

Source: llm_adapter@2026-07-13

Confidence: high

Bugfix Medium

Re‑creates idioms.md template and warns on refresh when the file is missing, avoiding permanent loss of taught idioms.

Re‑creates idioms.md template and warns on refresh when the file is missing, avoiding permanent loss of taught idioms.

Source: llm_adapter@2026-07-13

Confidence: high

Bugfix Medium

Reports profile corruption when core artifacts are missing or corrupt in get_status and detect_repo tools.

Reports profile corruption when core artifacts are missing or corrupt in get_status and detect_repo tools.

Source: llm_adapter@2026-07-13

Confidence: low

Bugfix Low

Catches and repairs fix‑wave regressions such as placeholder hops in blast‑radius parity and crashes on damaged conventions.json.

Catches and repairs fix‑wave regressions such as placeholder hops in blast‑radius parity and crashes on damaged conventions.json.

Source: llm_adapter@2026-07-13

Confidence: high

Bugfix Low

Surfaces parse failures for corrupt tsconfig.json and pyproject.toml instead of silent swallowing.

Surfaces parse failures for corrupt tsconfig.json and pyproject.toml instead of silent swallowing.

Source: granite4.1:30b@2026-07-13-audit

Confidence: low

Bugfix Low

Corrects no‑remote monorepo workspace repo_id, summary, and nested_profile_warnings.

Corrects no‑remote monorepo workspace repo_id, summary, and nested_profile_warnings.

Source: granite4.1:30b@2026-07-13-audit

Confidence: low

Bugfix Low

Consumes NestJS implements heritage for class contracts.

Consumes NestJS implements heritage for class contracts.

Source: granite4.1:30b@2026-07-13-audit

Confidence: low

Bugfix Low

Captures Python async/await signal handling correctly.

Captures Python async/await signal handling correctly.

Source: granite4.1:30b@2026-07-13-audit

Confidence: low

Full changelog

Whole-plugin from-scratch real-world QA campaign: 29 parallel testers exercised
the real plugin surface (real hook binaries, in-process MCP tools, skills, and
infra) against the real profiled repos across TypeScript/Ruby/Python and every
supported framework. 54 findings were confirmed and remediated, each reproduced
before fixing and re-verified by an adversarial pass; the fix wave itself was
verified, catching and repairing 3 fix-introduced regressions. Full unit suite
green (5413 passed), ruff clean.

Fixed

  • Canonical-witness recency tiebreak was defeated by per-file clock jitter
    (P1).
    select_canonicals forwarded now=None, so every per-file recency
    weight re-evaluated time.time(); two files sharing a commit epoch got weights
    differing by sub-millisecond jitter, and because recency sorts above typicality
    that jitter picked a near-empty aggregator over the real majority implementation
    as the archetype witness. The clock is snapshotted once per pass.
    select_canonicals in bootstrap/canonical.py.
  • A hex/unicode-escaped secret in a single literal bypassed the deny (P1).
    KEY = "\x41\x4b\x49\x41..." (a fully-escaped AKIA token) never hit the
    concat-fold path, so the escapes were never decoded and the raw bytes never
    matched. A numeric-escape-decoded scan pass (\x/\u/\U only, so line
    numbers stay truthful) now runs alongside the fold pass. _scan_with_concat_fold
    in lint_engine.py.
  • rsync/scp/dd and interpreter one-liners laundered a blocked secret past
    the Stop backstop (P1).
    The destination-arming token list covered only
    mv/cp/ln/install; a rsync a b, dd if=a of=b, or python -c "open('x','w').write(secret)" relocated a blocked secret to an unarmed path.
    The extractor now arms rsync/scp positional destinations, dd of= targets, and
    the quoted write-sink path inside a python -c/node -e/ruby -e one-liner.
    _extract_bash_write_targets in hook_helper.py.
  • A Bash-written no-archetype file, or a Bash rm, was invisible to the
    crossfile-existence check (P1).
    The recorder skipped a clean no-archetype file
    and never saw a fresh rm, so a sed/rm that broke an importer bypassed the
    turn-end deny that the Edit path enforces. Clean ts/js/rb/py Bash writes are now
    recorded (parity with Edit), and a Bash-deleted ts/py module is recorded so the
    Stop prune feeds it to the FP-safe deleted-module advisory. hook_helper.py.
  • forwardRef/memo-wrapped React components were invisible to every TS
    comprehension tool (P1).
    const X = forwardRef((props, ref) => {}) returned
    null from the name resolver (the arrow's parent is the wrapper call, not the
    binding), dropping the component from search/callers/dup. The resolver now
    ascends through forwardRef/memo/observer/connect wrappers to the binding
    name. callableNameOf in scripts/ts_dump.mjs.
  • get_status and detect_repo reported a healthy enforce panel over an
    unloadable profile (P1/P2).
    A missing/corrupt core artifact (archetypes/
    canonicals/rules), a generation mismatch, an absent profile.json beside live
    artifacts, or a corrupt conventions.json makes load_profile_dir refuse and the
    hooks fail open, yet both tools rendered mode=enforce. They now report the
    profile corrupt, matching get_pattern_context. _profile_unrenderable_status
    and detect_repo in tools.py.
  • Security-idiom prose silently disabled ALL taught idioms (P1). An idiom
    whose rationale said "never call eval() on user input" or "avoid rm -rf"
    tripped the prompt-injection scan and dropped the entire idiom block from every
    context-injection path. The dangerous-code sinks (eval/exec/rm-rf/os.system) are
    now flagged only in an imperative context; a negated/advisory usage passes, while
    an offensive always run eval(user) still blocks. _looks_suspicious in
    tools.py.
  • Deleting idioms.md then refreshing was a silent permanent no-op (P1).
    Refresh noop'd and never recreated the template or warned, so taught idioms
    vanished. Refresh now re-derives once when idioms.md is missing (writing a
    fresh template and surfacing the "restore from git history" warning), then
    self-heals. _refresh_repo_locked in tools.py.
  • The statusline trust field bypassed the line-protocol sanitizer (P1).
    $p.name was stripped of control/bidi/ANSI chars but $p.trust was
    concatenated raw, so a crafted cache could forge entries and inject terminal
    escapes. Both fields now share the sanitizer. bin/chameleon-statusline.sh.
  • Enforcement/quality fixes (P2/P3). get_status remediation text no longer
    tells the user to /chameleon-refresh a too-new-schema profile (refresh refuses
    it); the Tier-2 witness lead honors confidence_band (a low-confidence AST match
    no longer says "mirror closely"); the Rails inheritance rule exempts a
    third-party gem base (LookbooksController < Lookbook::PreviewController); the
    inline-ignore override is no longer double-counted across the Pre/PostToolUse
    gates; disable_session recognizes an edit-only session via its enforcement
    state; the merge driver's *.chameleon-merge.tmp orphans are swept; a new Flask
    blueprint is no longer mislabeled util; teach_competing_import's npm-package
    warning is gated to TS/JS profiles.
  • Independent-file findings (P2/P3). Corrupt tsconfig.json/pyproject.toml
    parse failures are surfaced (not silently swallowed); no-remote monorepo
    workspace repo_id/summary/nested_profile_warnings corrected; NestJS
    implements heritage consumed for class contracts; Python async/await signal
    captured; absolute first-party phantom-import detection added; Data.define
    block-form class methods attributed correctly; root-level TS extension bucketing,
    stale reverse_index schema handling, pnpm-workspace without packages:, the
    duplication body-hash, blast-radius caller-edge parity, and several doc/skill
    drifts fixed. orchestrator.py, conventions.py, phantom_imports.py,
    prism_dump.rb, libcst_dump.py, signatures.py, symbol_index.py,
    workspace.py, function_catalog.py, blast_radius.py, enforcement_calibration.py,
    tool_config.py, violation_class.py, extractors/python.py, clustering.py.
  • Fix-wave regressions caught by the verify pass and repaired. The
    blast-radius parity fix leaked <anonymous>/<module> placeholder hops into the
    correctness-judge advisory — the judge now trims them while the read tools keep
    the parity. The inheritance-calibration fix crashed the read path on a null
    frequency/consistency in a damaged conventions.json — coerced to fail-open. The
    absolute-phantom-import fix false-flagged (and could BLOCK) a real PEP 420
    namespace-package import — the full dotted path is now confirmed absent before
    flagging.

Known remaining (tracked)

  • naming-convention-violation/inheritance-convention-violation lint messages
    carry no parseable line number, so the pr-review hunk-gate mis-buckets
    pre-existing drift in a changed file.
  • posttool-verify/lint_file cost scales with LINE count, not bytes; a 100KB
    many-short-line file can exceed the hook's internal timeout and drop its lint.
  • Partial refresh carries function_catalog.json verbatim, so
    get_duplication_candidates misses duplication introduced in that refresh until
    the next full refresh.

Weekly OSS security release digest.

The CVE patches and breaking changes that affected production tools this week. One email, every Sunday.

No spam, unsubscribe anytime.

Share this release

Track Chameleon

Get notified when new releases ship.

Sign up free

About Chameleon

All releases →

Related context

Earlier breaking changes

  • v3.0.0 MCP surface folded from 48 tools to 19; remaining 32 operator tools become actions on three dispatchers.

Beta — feedback welcome: [email protected]