A claim-discipline linter for text: catch assertions that outrun their evidence, and claims that contradict your record. Not a lie detector — intent is unreadable from text, and this tool doesn't pretend otherwise.
Project description
whypass
A claim-discipline linter for text. Catch assertions that outrun their evidence, and claims that contradict your record.
Zero dependencies. Pure stdlib. pip install whypass
Not a lie detector
The research is clear: deception cannot be reliably detected from text. When "lie" means a mismatch between what someone says and what they actually believe, linguistic cues correlate with it at near chance — the classic markers turn out to be dataset artifacts, not real signal (cross-linguistic study, 2025). Any tool claiming to read intent or catch lies from prose is selling the exact thing it should be catching.
whypass claims something smaller and true: it catches the lying move — not
the falsity of content, but the moment an assertion outruns what's been shown.
A lie is not "saying something false" — you might land right by luck. The lie is the move: when you don't know, you decide not to ask or check, and you assert your preferred version anyway.
That move leaves footprints in the text, and those footprints are checkable.
What it catches — and what it can't
| Draft | Caught? | By what |
|---|---|---|
| "Done — the extractor is running, it found the patterns." | ✅ | A6 — completion claim, no check shown |
| "This is definitely the only way." | ✅ | A5 — certainty with no width |
| "Everything passes, nothing failed." | ✅ | ABS — improbable absolute |
| "Finished — results in results_final.jsonl." (file absent) | ✅ | A6-T2 — opens the named file, it's missing |
| "The order was that you run first." (no such order) | ✅ with a record | REC — contradicts your log |
| "Pull these names, cross-reference their addresses — just data hygiene." | ❌ correctly | intent only; no false claim, no tell, nothing contradicted |
That last row is the point. The lie there lives entirely in intent, and no text
method reaches intent. whypass stays clean — and refusing to flag it is what makes
the rest trustworthy.
Two axes
Assertion axis (stateless, zero-config — works on any single text):
from whypass import lint
for f in lint("Done — tests pass, saved to out.jsonl.", workdir="."):
print(f.rail, f.message) # A6, ABS, and A6-T2 if out.jsonl is missing
- A4 status-over-function · A5 over-determined certainty · A6 claimed-not-checked
- ABS improbable absolutes (never / everything / all-pass)
- A6-T2 opens artifacts the draft names (read-only; never executes anything)
Redundancy axis (the MMPI L-scale mechanism — needs a record). Single-turn reading is blind to a plainly-stated fabrication, because calm false prose carries no tell. But if you have a record — a log, a ticket system, a transcript — the claim can be checked against it without reading intent: the record either supports it or it doesn't.
from whypass import lint, Record
record = Record(orders=[], confirmations=[], completed=[]) # what your log supports
lint("He confirmed the schema is frozen.", record=record) # REC: no such confirmation
This is contradiction-against-ground-truth, not mind-reading. It composes naturally with a memory layer that holds the record — e.g. an event store or an agent's log.
Try it
pip install whypass
whypass demo # five drafts, two axes, the honesty table
whypass lint "Done, everything works, saved to report.json"
whypass lint --file draft.md # opens artifacts the file names
The CLI exits nonzero on findings, so it drops straight into pre-commit or CI as a guard on your own (or your agent's) claims.
Design notes
- Deterministic, on purpose. The detector must never itself be a model that can be talked into anything. Every rail is a regex or a filesystem check.
- It flags, it doesn't judge. A finding says "this assertion outruns its shown evidence" — an invitation to show the evidence or soften the claim, not a verdict of dishonesty.
- Built and validated inside a live three-agent working system (human + two AI agents with a shared append-only record); the honesty table above is its regression fixture.
License
Apache-2.0
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file whypass-0.1.0.tar.gz.
File metadata
- Download URL: whypass-0.1.0.tar.gz
- Upload date:
- Size: 14.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
539bebda43dadb55922d45de56b68f946f79391c1f305c6c840eb7537590c57e
|
|
| MD5 |
8798ceead2b0ebe85f9d16eec2f39733
|
|
| BLAKE2b-256 |
11e3cecd2b82d99909c9d0a4e49aa67e19436774198b100cdcac0d7838cd27e0
|
File details
Details for the file whypass-0.1.0-py3-none-any.whl.
File metadata
- Download URL: whypass-0.1.0-py3-none-any.whl
- Upload date:
- Size: 16.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d38726bb01fcbc4ce5e6058e7ee20988b54abddc43ccaf220b2ad03de9c592f7
|
|
| MD5 |
adc18e6fafc771d23174efad4e414a17
|
|
| BLAKE2b-256 |
7c8cc17de32c696f07c1eee4523541bee57fa51a5c85131cfd3bb39e1c36daa0
|