Craft: Jev Sheets
Jev Sheets is a spreadsheet where a column header is a typed question and Jev answers it for every row. The person brings a file they could never read in full. The craft is wording questions so the answers are right and the confidence is honest, then turning the answers into findings a person can act on. A made-up sheet is only the fallback when they have no file at hand.
How one row is judged
For each row the viewer makes ONE call. The state is the row (its text plus plain fields like
from or plan). The questions are all the Jev columns, asked in parallel. Questions cannot see
each other, and nobody sees truth or group.
state { "text": "You charged my card twice. Refund it today.", "plan": "pro" }
questions urgent noul "Urgent?"
team choice billing = payment or invoice problems | tech = bugs and outages | sales = ...
anger score calm < annoyed < furious
answers urgent 0.86 team billing (0.84) anger annoyed (0.79)
Answers are cached by row text plus column definition. So after an edit to sheet.json, only the
cells that changed are asked again. Rewording one header refills one column.
The header grammar
Urgent? yes or no (ends with ?)
Team: billing | tech | sales choice (2 to 255 options)
Team: billing = invoices, refunds | tech = bugs choice with meanings (always prefer this)
Anger: calm < annoyed < furious score (2 to 10 levels, lowest first)
Urgency score (bare word: low < medium < high)
In sheet.json a column is a header string or { "id": "team", "header": "Team: ..." }. Use an
id whenever rows carry truth, so rewording the header does not orphan the labels.
Working on the person's own file (the main job)
- Get it in. They press Choose a file in the pane or paste rows, and
"source"appears insheet.jsonby itself. Or they give you a path: copy it into the workspace and set"source"(an Excel.xlsxworks as it is: the first sheet is read). A PDF, a chat export or a folder of notes: convert it to a.csvor.jsonlin the workspace, one row per item, keeping a column that says where each row came from. Long documents: one row per paragraph or clause. - Look. Read the header and about twenty rows. Say in two lines what is in it. Set
contextto one sentence about what a row is, andtextColumnif the guess was wrong. - Aim at their decision. If they already said what they want to know, do not ask again. If
not, ask what they are trying to decide. Then write three to five questions aimed at that. Mix the
types: one yes or no, one choice with a meaning for every option and an
other, one score. The other columns are part of what Jev reads, so a question can lean on them ("Worth a call today?" can use aseatscolumn). - Check the save took, then read the answers. In
.harness/verdict.json,sheet.loadedAtmoves within two seconds of a save, and the fill is done whensheet.cellsFilledequalssheet.cellsTotal(30 to 40 seconds for every 1,000 rows with a live key;"client": "mock"means no key, so stop and say so).answers.csvhas arownumber, the text, the file's own columns, and for each question the answer as a word plus<Name> confidence. There are no truth labels, so judge a question by how many cells sit under the review line and by reading the rows behind the numbers. - Write
findings.md. What was asked and of how many rows. For each question the count and share of every answer. For each finding that matters, three to five word-for-word quotes with row numbers (lead with the answer in the first five lines). A cross-cut or two when it says something ("of the 212 crash reports, 61% also say they may leave"). What Jev was unsure about. The next question worth asking. Count withnode "$JEV_DSH/toolchain/count.mjs"(counts,--by a --and bcross-cuts,--where a=b --rows 10to read the rows behind a number,--unsure a,--find "words"), never by eye. - Sharpen and repeat. Split a fat
other. Reword a column whose answers sit near 50%: a yes or no about intent usually wants to become "says in words that…" or a three-way choice. Try the rewording on ten hard rows throughtoolchain/jev.mjsfirst, because a full pass takes most of a minute per 1,000 rows however few columns changed.
Keep their data in the workspace. Quote only what the report needs.
Building a made-up sheet (when they have no file)
- Pick the unit of a row (a message, a review, an application, a bug report) and write
contextin one sentence. - Write 40 to 200 rows of made-up text, one to three sentences each. Vary length, tone and who is
writing. Add one or two plain fields if they help (
from,plan,channel,stars). - Write three to five columns. Mix the types: one yes or no, one choice, one score.
- Label
truthfor the starter columns on every row. It is what lets the pane show accuracy. - Write a block of mixed-signal rows, about a quarter of the sheet, and mark them
"group": "mixed". Mark the rest"group": "clear". Good mixed rows pull two ways at once: polite words with an angry point, "no rush" with an outage, a billing question inside a sales request. - Add six to ten
suggestions: more headers a person could try on the same rows. - Run
node "$JEV_DSH/toolchain/check.mjs".
Reading the verdict
The viewer writes .harness/verdict.json. Read sheet.columns[]:
{ "id": "team", "accuracy": 0.93, "labelled": 60, "underReviewLine": 11, "avgConfidence": 0.78,
"weakest": [ { "row": "x56", "text": "Before we sign for 200 seats, legal needs...",
"answered": "tech", "confidence": 0.47, "truth": "sales" } ] }
and sheet.groups for the average confidence of clear rows against mixed rows.
- Low accuracy on clear rows means the question is unclear. Look at the weakest rows. Usually two options overlap, or an option has no meaning written down. Reword and save.
- Many cells under the review line on clear rows means the options are too close together, or a score has too many levels. Merge or rename them.
- Mixed rows as confident as clear rows means the mixed rows are not really mixed. Rewrite them so the two signals are about equally strong.
- A confident wrong answer is the most useful row in the sheet. Tell the person about it.
Change one column at a time, save, and read the verdict again. Report what moved.
The offline mock
Without a Jev key, a local mock answers. On a person's own data it is not good enough to act on: the pane says so, and the fix is a key pasted into the pane's live panel, never into the chat. It counts word cues: the words of the header, the option names and their meanings, plus a small built-in list for common ideas (urgency, anger, billing, bugs, sales, refunds, churn, sentiment, spam, security). It knows nothing else. On the mock, a column only works if the rows use words that the option meanings also use. So write meanings with the words a row would really contain. The pane badges the mock as MOCK, and its accuracy says nothing about live Jev.
Definition of done
On the person's own file: sheet.json passes check.mjs, context is set, every choice option has
a meaning, you read answers.csv and the rows behind the main numbers, and findings.md is written.
On a made-up sheet:
sheet.jsonpassescheck.mjs.- Made-up rows on the asked topic, with a mixed-signal block and truth labels.
- Every choice option has a meaning. Scores have clear, ordered levels.
- You read the verdict and reported: accuracy per column, cells under the review line, the average confidence of clear against mixed rows, and the next question you would sharpen.