The Rubble Assayer
Hand it an untrusted blob or a prompt and it tells you: real signal, machine rubble, or a lie you didn't ask about.
The ingredients 3 gifts
Pick your depth — take the quick way in, the full walk-through, or the deep build. Same recipe, your call today.
Quick you want a fast read on a string you don't trust
Hand a suspect string to three cheap tests: is it human-readable text (legible), does it compress like structured data vs. random (grain), and what does a prompt fail to constrain (confessional). You get three signals, not one.
Start by running the three and just PRINTING their verdicts side by side. The interesting work is deciding what to do when they disagree.
signals = {
"readable": legible(blob), # 'probably text, 0.6'
"structure": grain(blob), # 'compresses like JSON' vs random null
"gaps": confessional(prompt), # what the prompt fails to bound
}
verdict = fuse(signals) # <- your policy: what disagreement means
Working you want to understand the three interrogations
The five parts below walk it: legible guesses readable-text vs machine-rubble with a confidence, grain compares compression against a live size-matched random null, confessional reads what a prompt fails to constrain from a closed checklist.
You build the assay policy and its verdict fusion — the interesting part is what you DO with three signals that disagree.
Deep you want to know what none of it proves
None of these prove INTENT. grain can tell you a string is suspiciously compressible; it cannot tell you the padding is an attack rather than a coincidence. legible's confidence is about readability, not safety — perfectly readable text can be perfectly malicious. confessional reads a closed checklist; a novel gap not on the list is invisible.
Three honest guesses fused is far better than one confident one — but it's a triage, not a verdict on safety. The fusion policy is where your real judgment lives.
For real use: tune the fusion to fail toward quarantine on disagreement, and treat any single high-confidence 'rubble' as enough to hold, not to pass.
The idea
You are handed a string and asked to trust it — a scraped field, a decoded payload, a prompt someone swears is safe. This assembly interrogates it three ways instead of one. legible guesses whether a string is human-readable text or machine-drawn rubble, and says how sure it is. grain compresses the data and compares its ratio against a size-matched random null model drawn live — it can tell structure from noise where a human eye can't. confessional, pointed at a prompt, reads back what the prompt does NOT constrain — the gaps you didn't think to close. Together they form an assayer: not 'is this valid?' but 'what actually is this, and what is it quietly not saying?'
The parts + how they wire
The blob enters confessional first when it's a prompt — it admits, against a closed checklist, which constraints the prompt leaves open (no length bound, no format lock, no refusal clause) → whatever survives goes to legible, which scores text-vs-rubble with a confidence number, so encrypted or corrupted or binary-masquerading-as-text gets flagged → grain is the fold that closes the verdict: it measures the string's real compressibility against a live random baseline of the same size, separating 'structured content' from 'high-entropy noise' from 'suspiciously compressible' (a red flag for padding or repetition attacks). The output is a three-axis assay card: readable?, structured?, and what-it-doesn't-constrain.
The one piece you build
The assay policy and its verdict fusion — several components, because the interesting part is what you DO with three disagreeing signals. legible says 'probably text, 0.6.' grain says 'compresses like structured JSON.' confessional says 'this prompt sets no output-length bound.' You build the router that feeds the right gift for the input type, the thresholds that turn three scores into one classification, and the escalation rules for when they conflict — which is exactly when something interesting is happening.
The technical breakdown
The three gifts are strong precisely because they measure different, non-overlapping things. legible is a surface classifier — character distribution, run structure — cheap and easily fooled alone. grain is information-theoretic: it draws a fresh random null of matched size every run and compares compression ratios, so its 'this is structured' verdict is calibrated against actual noise rather than a fixed threshold that drifts across data types. confessional is orthogonal to both — it doesn't look at entropy at all, it reads a prompt against a closed list of constraint types and reports absences. The fusion is where your judgment lives: agreement across all three is a confident verdict; disagreement (legible says rubble, grain says highly structured) is the signal that you're looking at something engineered — encoded, encrypted, or adversarial. This is a real subsystem, not glue: ~200+ lines of input routing, per-gift thresholding, conflict-resolution rules, and a verdict schema that carries all three raw scores so a human can overrule the fusion.
The honest edge
None of these prove intent. grain can tell you a string is suspiciously compressible; it cannot tell you the padding is an attack rather than a coincidence. legible's confidence is a guess about readability, not about safety — perfectly readable text can be perfectly malicious. confessional reads what a prompt fails to constrain from a closed checklist; a novel gap not on the checklist is invisible to it. The assayer's real output is not a safe/unsafe verdict — it is a well-characterized description of an unknown, with every raw score exposed. It tells you what you're holding and where the three measures disagree. Deciding to trust it is still yours.
These are ingredients, not instructions you have to follow. Take these parts and cook something — the recipe as written, a variation, or something we'd never have thought of.
Built it, got stuck, or found a mistake? Shea wants to hear it — success stories, questions, and bug reports all land in the same inbox: