Skip to content

fix(crush): JSON keeps structural errors, not the bare word "error" - #10

Merged
initializ-mk merged 1 commit into
mainfrom
fix/json-error-keep
Sep 15, 2026
Merged

initializ-mk merged 1 commit into
mainfrom
fix/json-error-keep

Conversation

@initializ-mk

Copy link
Copy Markdown
Contributor

Bug

The JSON crusher's absolute keep used the broad looksError substring, so an array where every row merely mentions "error" — e.g. Go signatures func Handle(ctx context.Context) error — pinned every row and compressed 0%. An error return type is not an error.

Fix

  • looksHardError (new, relevance.go) matches only structural error signals: uppercase log levels, error:/panic:/error[E0433], line-start level keywords, {"level":"error"} / level=fatal, and k8s failure states (CrashLoopBackOff, OOMKilled, …). Case-sensitive by design — loggers emit uppercase levels. looksError stays as the broad soft-ranking signal.
  • JSON crusher absolute keep is now MustKeep + looksHardError (not looksError). Middle rows collapse by lineSig signature to one representative per shape (highest-scoring member), and the distinct set is kept to an adaptive budget (adaptiveKeepCount, jsonMinKeep 3 / jsonMaxKeep 40) — parity with the search/adaptive path.

Tests (crush/json_regression_test.go)

  • 400-row array of error-returning Go signatures now compresses: 37,581 → 965 bytes (was passthrough).
  • A genuine {"level":"FATAL"} row still survives verbatim while its INFO siblings collapse.
  • Full existing suite green (the behavior change doesn't regress prior JSON tests); make check clean.

Targeting a v0.4.1 patch release.

The JSON crusher kept every row matching the broad looksError substring,
so an array of Go signatures — `func H(ctx context.Context) error` — pinned
all 400 rows and compressed 0%. The "error return type" is not an error.

Split the floor: looksHardError (new, in relevance.go) matches STRUCTURAL
signals only — uppercase log levels, `error:`/`panic:`/`error[E0433]`,
line-start level keywords, `{"level":"error"}` / `level=fatal`, k8s failure
states (CrashLoopBackOff, OOMKilled, …), case-sensitive because loggers
emit uppercase levels. The JSON crusher's absolute keep is now
MustKeep + looksHardError; the broad looksError is demoted to a soft
ranking boost. Middle rows collapse by lineSig signature to one
representative per shape (the highest-scoring member), and the distinct
set is kept to an adaptive budget (adaptiveKeepCount, jsonMinKeep 3 /
jsonMaxKeep 40) — headroom-parity with the search/adaptive path.

Regression tests (crush/json_regression_test.go): a 400-row array of
error-returning Go signatures now compresses (37581 -> 965 bytes, was
passthrough), and a genuine {"level":"FATAL"} row still survives verbatim
while its INFO siblings collapse. Full suite green. No release tagged.
@initializ-mk
initializ-mk merged commit b335249 into main Sep 15, 2026
1 check passed
@github-actions

Copy link
Copy Markdown

🔎 Grype — no fixable vulnerabilities ✅

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant