Features
- Font analyzer (sfnt/WOFF/WOFF2/EOT) and media analyzer (WAV, AIFF, MP3, MP4, ICO, GIF, BMP, WebP)
- SVG is its own rule type
- is: base64 string validator
- Symbol conditions gained argument positions (index:) and value provenance (from: with transfer models)
- downgrade: gained scope: (defaults to file) so one archive member can't silence a rule in another.
- New analysis_gaps field reports incomplete analysis in text and JSON, independently of findings.
- cleave validate fixtures assert required/forbidden trait hierarchies and required analysis gaps.
- Nine new validators, and hostile composites now need two notable+ legs instead of one.
- Unparseable trait files warn on every run, not just the run that rebuilt the cache.
- PE version-info extraction now enumerates the StringTable structurally, surfacing custom vendor keys like CompiledScript
- PE FileDescription projects to identity title when filefacts supplies none.
Fixes
- Cache stores key on the traits revision the analysis ran under
- Archive/decoded roots are never rebuilt from the leaf cache, which dropped children.
- Findings demoted by their own downgrade: are kept instead of stripped away entirely.
- Call symbols come from filefacts, giving chained calls one matchable spelling (open.read)
- C functions are named by identifier, not by their whole signature.
- Proximity evidence keeps per-offset locations and the winning window's real matched text.
- MSI/OLE/OOXML and Java class reports populate strings, so type: text rules work.
- section: any is honored by the matcher and spans all mapped sections
- JAR class triage ranks classes by constant-pool salience rather than attacker-controlled archive order
- Embedded-binary scanning dedupes by content and samples across the file
- Mach-O ad-hoc signing no longer double-reports
- Hex patterns under the concrete-byte floor warn instead of silently never matching.
- Decoded-layer folding rewrites parent IDs, src, and composite source edges instead of orphaning them.
- Source string retention is bounded in aggregate
- cleave test-rules evaluates string conditions with their full parameter set
Optimizations
- Match locations are collected only for traits that can reach a proximity constraint.
- JAR salience scoring shares the YARA triage read rather than adding a second archive walk
- Embedded-binary header checks are bucketed per file region (8,192 checks / 1,024 candidates per scan)
- Java class and other analyzers reuse the caller's filefacts parse instead of reopening it.
- wasmtime/cranelift at opt-level = 2 and test = false on helper bins cut cold-build time.