This release includes 1 security fix for security teams reviewing exposed deployments.
Topics
+12 more
Affected surfaces
Summary
AI summaryClosed a supply‑chain scanner evasion that allowed malicious dependencies to bypass detection.
Full changelog
A real-usage hardening round on the two review skills (/chameleon-pr-review,
/chameleon-receiving-code-review), driving every engine tool the skills depend
on against live-bootstrapped TypeScript, Ruby, and Python repos and cross-checking
each field/enum the skill reads against the tool's actual return. Five contract-drift
gaps (three of which silently no-oped a review pass) were corrected, and one
supply-chain-scanner evasion was closed at the engine.
Fixed
-
get_duplication_candidatesshape drift silently disabled the duplication
pass. pr-review Step 2.9b and receiving Step 3 told the model to read the
returned "candidates" and cite each candidate'ssymbol/path/excerpt. The
tool actually returns{found, file, matches}— the pairs are under
data.matches(there is NO top-levelcandidates), each match is
{function, candidates}, and a candidate's fields arename/file/body_excerpt
(neversymbol/path/excerpt). A model following the old wording read the
wrong keys, got nothing, and never raised a duplication finding. Both skills now
name the exact shape. (skills/chameleon-pr-review/SKILL.md,
skills/chameleon-receiving-code-review/SKILL.md) -
typecheckwas documented as a scalar but is a dict, mis-keying the auto-pass
routing. pr-review Step 3h wrote the state astypecheck: unavailableand
renderedTypecheck: N changed file(s) with type errors. The engine returns
typecheckas{status: "unavailable"|"clean"|"errors", ...}(unavailable adds
reason, errors addsfilesanddiagnostics). The skill now reads
typecheck.status/typecheck.reason/typecheck.diagnostics/typecheck.files
and the example output matches the render instruction. (skills/chameleon-pr-review/SKILL.md) -
scan_dependency_changesfinding fields were unnamed, inviting a wrong-key
read. Step 2.5 routed findings by their check type but never named the field;
a model assuminglint_file'srule/lineshape would read nothing. The finding
is{check, severity, path, evidence, message, detail}— the type ischeck
(notrule), the cited line isevidence(notline), and severity is the
literal"FIX"/"NIT". Also documents thatmanifests_changed/summaryare
absent on a degraded/failed scan anduncovered_manifestsappears only when
non-empty. (skills/chameleon-pr-review/SKILL.md) -
get_callersgrade set was stale. Step 2.9d listed the deterministic grades
as a closedsame_file/import/constant_receiverset, but the calls index now
also recordstyped_property(TypeScript dependency-injection edges, v2.49) and
module_attribute(Python module-attribute calls, v2.50). The skill now lists the
full set, treats it as open, and names the caller-site fields (caller, not
name). (skills/chameleon-pr-review/SKILL.md) -
Cross-file finding field names were left implicit. Step 2.9c
(get_crossfile_context) and Step 2.9e (get_contract_breaks) described the
citation semantically without naming the fields; the crossfile importer file:line
in particular lives underfinding.sites({path, line}), not a flat
file/line, and a contract break's symbol isnamewith
old_required_positional/new_required_positional. Both are now named exactly.
(skills/chameleon-pr-review/SKILL.md) -
A partially-packed dependency object evaded the supply-chain scanner without
tripping the minified-manifest guard.scan_dependency_changes's per-key
scanners are line-oriented, and theminified-manifestguard fired only when the
WHOLE manifest was a single{...}line. Apackage.jsondiff that packs a
dependency/scripts container onto one physical line —
"dependencies": { "evil": "git+ssh://…", "left-pad": "^1.0.0" }— while the file
stayed multi-line defeated the install-script/non-registry-source/new-dependency
checks AND slipped past the guard, reading as a silent clean add. The guard now
also flags such packed-container lines (detail.reasonpacked-container-line),
scoped to dependency/pin/scripts containers so a legitimately-inline
"repository": {...}/"engines": {...}never false-fires. The scope also covers
npmoverridesand yarnresolutions— they pin a TRANSITIVE dependency to an
arbitrary version or source, so a packed"overrides": { "lib": "git+ssh://evil" }
is the same non-registry-source evasion (the unpacked form was already caught
line-by-line; the packed form slipped both scanners). Verified with real packed
and one-per-line diffs across the false-positive and evasion cases.
(mcp/chameleon_mcp/dep_diff.py,skills/chameleon-pr-review/SKILL.md)
Security Fixes
- Closed supply‑chain scanner evasion where partially packed dependency objects (e.g., a single-line "dependencies": {...} block) bypassed the minified‑manifest guard; now flagged with detail.reason `packed-container-line`.
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
About Chameleon
All releases →Beta — feedback welcome: [email protected]