András Horváth’s Vibefilter adds a semantic filter to Filament, a Laravel admin-table toolkit: type “The customer is angry,” score the relevant rows with Jev, and retain those above an application-selected threshold. The useful contribution is the surrounding plumbing, not another promise that classifiers replace SQL.

I inspected the README, TypeSafe driver, scorer, text normalizer, and table filter at revision 9677e04464d52d7917f0c6dec26345c0dcc26402. I did not run the package: this host has neither PHP nor Composer. No live model result or performance claim was reproduced; this is not a security audit.

Narrow first, score second

  • Existing search and ordinary filters determine the candidate rows before Jev sees their selected text columns.
  • The inspected driver defaults to 100 rows per request and 10 concurrent requests, with one noul question per randomly tagged row.
  • Cached scores are keyed by normalized statement, text content, and provider/model identity; changed text or model means fresh scoring.
  • A configurable unscored-row limit asks the user before sending a larger workload; changing the threshold reuses existing scores.

Failure changes what the table means

Retryable transport, rate-limit, and server failures trigger retries and then a single split of the failed batch. Successful batches are saved rather than discarded.

  • With some scores available, the filter shows only passing scored rows and warns that the result is incomplete.
  • With no scores available—or while awaiting large-run confirmation—the table stays unfiltered.
  • The candidate query loads all selected rows before checking the API-work limit; this is not a memory bound for large tables.

That behavior can be reasonable for an exploratory interface. It must not become an access-control rule or an assumption that every omitted row is a negative decision.

Agreement is not accuracy

The maintainer reports 861 of 1,000 synthetic reviews agreed with their model-written mood labels at a 0.8 threshold. The same language models wrote and labeled the reviews; this is not an independently human-labeled evaluation, and choosing the threshold on that dataset does not establish generalization.

The README also claims about one second and $0.003 for a fresh statement on 1,000 short reviews. These are maintainer-reported, unreproduced API-work figures, not total application cost or guaranteed latency.

Keep the boundaries explicit

Selected text leaves the application for hosted scoring. Random tags avoid sending real record IDs, but do not anonymize names or sensitive details inside the text. The inspected answer parser requires numeric noul values but does not explicitly enforce a finite 0–1 range.

Typed output is not a correct decision. The README’s “calibrated probability” language needs validation on the intended data. Use representative labels, review missed rows, preserve ordinary authorization, and make incomplete results unmistakable.