A plain-language predicate still scans every eligible row
Version 0.2.1 turns a question such as the customer is angry into an ordinary PostgreSQL function call. jev() returns a boolean, jev_prob() returns a probability, and related functions assign a fixed choice or a score along named levels. The model produces judgments rather than prose, so the result can sit inside WHERE, ORDER BY, or GROUP BY without parsing a chat response. That is a neat fit for exploratory classification where exact SQL cannot express the distinction.
The cost model follows the executor. Every row that reaches jev() is judged, because the extension has no index or stored embedding to consult. Cheap SQL predicates should reject rows first, and LIMIT can stop read-ahead once enough results arrive. The default batch contains 20 rows, while up to twice the configured concurrency may be in flight. This suits a bounded slice of a table. A broad recurring query belongs in a materialized workflow or an indexed retrieval system.
What happened when we ran it
Our sandbox installed commit 8d9598d in 21 seconds. The step added 35 Python packages and occupied 37 MB on disk. The build then succeeded in 6 seconds. Our measurement setup was a fresh Debian container with 3 CPUs, 8 GB of RAM, Python 3.12, no secrets, and no elevated privileges. Pip-audit reported 0 known vulnerabilities in the installed Python environment.
The test step failed with exit 5 after 6 seconds. Pytest reported 0 passed and 0 failed out of 0, and the log ended with no tests ran in 0.01s. That means our command found no pytest cases; it does not show a product assertion failing. We measured the generic Python path, while the repository documents make docker-test for PostgreSQL and mock-API cases through pg_regress. We did not run that SQL regression route.
The checkout was 0.3 MB, with 41 files and roughly 250 lines of source. It includes a Dockerfile, 2 CI workflow files, and a regression test tree. Those signals make the empty pytest collection understandable, but they do not convert our failed command into a pass. A team whose standard gate invokes pytest will need to teach it the project's Make target.
PostgreSQL 14 through 17 and PL/Python rule out common managed hosts
The README limits pg-jev v0.2.1 to PostgreSQL 14 through 17 and requires plpython3u. Creating it needs a superuser because PL/Python is untrusted. The documentation explicitly excludes Supabase, Neon, RDS, and similar services that withhold either capability. Source installation uses PGXS to copy a control file and SQL into the server's extension directory; there is no native module to compile. PGXN and a project Dockerfile provide two other routes.
Running a query adds a service dependency. The default endpoint is TypeSafe's hosted Jev API, authenticated by an API key placed in the PostgreSQL server environment, a role setting, or a session. Version 0.2.1 also accepts a compatible local endpoint without a key. That option keeps rows on your network, but you still have to operate the model service and match the expected /v1/systemone request and response contract.
Whole rows leave PostgreSQL unless you make a narrower view
In v0.2.1, a call such as jev(tickets, ...) serializes the row supplied to the function. The README tells users to create a view containing only the needed columns when privacy or token use matters. Open issue 8 captures the resulting friction: someone classifying one name column from a 30-column table must create a view instead of passing the column directly. That is manageable for a stable production query and clumsy during quick analysis.
TypeSafe receives row contents by default, so regulated or confidential tables need a field-by-field review before anyone runs the function. Two guard settings can cap rows or characters sent during one statement, but both default to 0, which means off. Set them at the role or database level for shared systems. Relying on every analyst to remember a session command leaves both disclosure and spend controls optional.
The per-session cache saves repeat calls and can keep growing
In v0.2.1, answers are cached by row content and question inside the PostgreSQL backend session. Changing a threshold or rerunning the same question can reuse those results. New row and question pairs keep adding entries until jev_cache_clear() runs or the backend exits. The jev.max_prefetch_rows setting limits read-ahead behavior, not total answer-cache memory. A connection pool with several persistent backends can therefore maintain several separate caches.
The same boundary affects repeatability. jev-latest is the default model name, while a versioned model can be pinned in configuration. Pin the model, preserve the exact question, inspect jev_stats(), and record the threshold if a judgment influences a durable business decision. The extension supplies probabilities, but your application still decides what uncertainty is acceptable. Exact dates, arithmetic, and equality checks should stay in SQL.
Version 0.2.1 is active and still very young
GitHub showed 870 stars, 1 open issue, and a last push on October 3, 2026. Release v0.2.1 arrived that day, adding keyless local endpoints and clarifying cache bounds. Issue 8 opened on October 4, so there is current user activity as well as recent code movement. The repository itself was created on September 17, 2026. A fast early release cycle is encouraging, though 18 days cannot establish long-term upgrade or production behavior.
pg-jev earns a trial when you own PostgreSQL and need a human-like judgment over a small, carefully selected row set. Begin with a view that exposes only allowed columns, add an indexed SQL pre-filter, set both statement guards, and examine probabilities before choosing a cutoff. If the query must scan a large table every day, or the database lives on a managed host, the extension's central tradeoff has already made the decision for you.

