jevkit-lint
Static linter for TypeSafe Jev questions.
TypeSafe publishes a list of failure modes
for jev-1.13: it reads instructions literally, it cannot count, it reads dates
as text rather than ordered quantities, it loses accuracy on indirection. Most
of those are visible in your question definitions before you send anything.
jevkit-lint reads the definitions and tells you. It never calls the API, so it
needs no key and costs nothing to run in CI.
Unofficial and unaffiliated with TypeSafe.
Install
pip install jevkit-lint
Use
from jevkit_lint import lint
result = lint({
"urgency": {"type": "noul", "instructions": "How many days has the customer waited?"},
"team": {"type": "choice", "instructions": "Which team should handle this",
"criteria": {"billing": "Payment issues", "technical": "Bugs"}},
})
print(result.format())
urgency: error [JEV001] Question asks the model to count or do arithmetic.
found: How many
hint: jev-1.13 is not a calculator and does not count reliably. Iterate the
candidates in code, ask one Noul per item, and sum the answers yourself.
team: warning [JEV008] Choice has no no-match option.
found: billing, technical
hint: A Choice always returns one of its options. With nothing meaning 'none of
these', a state that fits no option still produces a confident-looking
answer. Add an explicit none/unknown option, or gate on a separate
presence Noul.
result.ok is True when nothing rose to an error, so it drops straight into a
guard:
if not lint(questions, state).ok:
raise ValueError("refusing to send a request that will not answer what we meant")
CLI
jevkit-lint request.json # a {state, questions} object, or bare questions
jevkit-lint cassette.jevl # lint every recorded request
jevkit-lint - < request.json # stdin
jevkit-lint request.json --strict # exit non-zero on warnings too
jevkit-lint request.json --format json
jevkit-lint --list-rules
Exit codes: 0 clean, 1 findings, 2 bad usage.
Rules
Each rule names the documented failure mode it comes from.
| Code | Rule | Failure mode |
|---|---|---|
| JEV001 | math-and-counting | Math and Numbers |
| JEV002 | date-comparison | Date and time comparison |
| JEV003 | generation-request | Generation |
| JEV004 | negation | Literal reading |
| JEV005 | vague-scoping | Literal reading |
| JEV006 | indirection | Indirection |
| JEV007 | noul-polarity | Contradictory instructions and criteria |
| JEV008 | choice-no-match | Common-sense structural invariants |
| JEV009 | choice-arity | Common-sense structural invariants |
| JEV010 | option-descriptions | Literal reading |
| JEV011 | score-levels | Literal reading |
| JEV012 | instructions-present | Literal reading |
| JEV013 | question-id-reference | Indirection |
| JEV014 | state-budget | Large state full of irrelevant detail |
| JEV015 | total-budget | Large state full of irrelevant detail |
| JEV016 | state-noise-ratio | Large state full of irrelevant detail |
| JEV017 | numeric-representation | Math and Numbers |
| JEV018 | duplicate-questions | Common-sense structural invariants |
Select or suppress by code:
lint(questions, select=["JEV001", "JEV002"])
lint(questions, ignore=["JEV008"])
What it cannot do
Adversarial content is a documented failure mode and is not linted. Whether a state is hostile depends on the content at runtime, not on the question definition, so a static rule would be theatre. Screen untrusted state at request time instead.
Token counts are estimates. jevkit deliberately does not bundle a tokenizer: TypeSafe does not publish which one Jev uses, and a confidently wrong count is worse than an honest approximation. The estimator errs conservative, so leave headroom near the limits.
License
MIT
Metadata
Release files for jevkit-lint 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| jevkit_lint-0.1.0.tar.gz | 14.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| jevkit_lint-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 29.0 kB
Release files / jevkit_lint-0.1.0.tar.gz
| Download URL | jevkit_lint-0.1.0.tar.gz |
|---|---|
| Size | 14.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
37c9616b72806c57fc4698450a86d47a3aba5f7d9880c7770db66beb5aabb87a
|
|
BLAKE2b-256 checksum How to use checksums |
a84a3ff6d64dc1f001053b29e12ab15e0e071363ed02ab6d2c5892178c797a74
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.10.12
|
Release files / jevkit_lint-0.1.0-py3-none-any.whl
| Download URL | jevkit_lint-0.1.0-py3-none-any.whl |
|---|---|
| Size | 14.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
c66c52ce1024126afb674ca1265b3709ca61ad7f713f65d51d4429bdabf8d3ed
|
|
BLAKE2b-256 checksum How to use checksums |
c8218d281df25920891d8d019a71c7fa52f75b1d87bbe43d543e2bf07576135c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.10.12
|