The case file format
Version 1. For the people who will read these files with code.
A case file is one fictional taxpayer in one folder. It holds what a preparer was given, the return that was prepared, and the reasoning that connects the two. This page describes version 1 of the format.
The Illinois sample is a complete case file. Every example below is taken from it.
Layout
7b46e35c/
case.json
given/
narrative.md
documents/
w2-lakeshore-cloudworks.pdf
1099b-calumet-harbor-securities.pdf
3921-lakeshore-cloudworks.pdf
key/
return.pdf
lines.csv
workpaper.md
The folder is named with the case’s short ID, or with your own ID for the case if you gave us one.
Everything under given/ is what a preparer, or a model, is allowed to see. Everything under key/ is the answer. A pipeline that builds prompts should read given/ and nothing else.
case.json
The manifest. It says what the case is and lists every file in it.
| Field | What it holds |
|---|---|
format |
Always ustaxlab-case/1 for this version. |
uid |
The case’s permanent ID: a random version-4 UUID. |
short |
The first 8 characters of uid. |
references |
Other IDs for the same case, by scheme. This is where your ID goes. |
title, summary |
What the case was built around, in a line or two. |
taxYear, filingStatus, jurisdictions |
The basics. Jurisdictions are US and US- plus the state code. |
taxpayer |
The name, and "fictional": true. |
documents |
Each source document: an id, what kind it is, who issued it, its file and page count. |
forms |
Each form in the return: a short key, its name, and the pages it occupies in return.pdf. |
return |
The return’s file and page count. |
redacted |
In a sample copy, what has been blacked out. Absent from a delivered case. |
files |
Every file with its side (given or key), size in bytes and SHA-256. |
given/narrative.md
Everything the preparer was told or handed, written out as prose in Markdown. It reads like a preparer’s notes: who the taxpayer is, what happened in the year, and what each document shows. Headings, bold text and tables are all allowed.
Each passage ends with its number and its source in square brackets:
Jordan explained the restricted stock income. It is two vests: **500 shares on March 15, 2025** at $58.40 a share, and **400 shares on September 15, 2025** at $58.00 a share. [N6, taxpayer]
Form 3921 from Lakeshore Cloudworks shows that Jordan exercised incentive stock options on **June 2, 2025**: 1,600 shares at an exercise price of $22.00 a share. [N9, 3921]
- A passage is a paragraph. It can also be a table or a list, with the bracket on the line after it.
- Passages are numbered
N1,N2and so on, in order. - The second word is the source.
taxpayermeans the taxpayer said so and no document shows it. Anything else is theidof a document incase.json. - Headings group the passages for a reader. They carry no meaning.
The narrative states what is known. It never states a conclusion about the return.
given/documents/
The source documents, as PDFs laid out like the real forms and statements. Each file is named for what it is and who issued it.
Documents are not only tax forms. Emails, letters, invoices, receipts and bookkeeping reports go here too. Each one has an id in case.json, so a passage of the narrative can name the paper it comes from.
key/return.pdf
The prepared return: the federal return and every state and city return the facts require, in one PDF, printed by the tax software.
key/lines.csv
Every line on the return that carries a figure other than zero, plus any zero that is the result of a decision. One row per line, with these columns:
| Column | What it holds |
|---|---|
form |
The form’s key from case.json, for example 1040 or SD. |
line |
The line on that form, for example 1a, 25c, or I.r1.g for Part I, row 1, column (g). |
label |
What the line is, in plain words. |
amount |
The figure on the return, in whole dollars. |
how |
How the figure got there. One of four words, listed below. |
from |
Where it came from. What goes here depends on how. |
decision |
The workpaper decision this line depends on, if any. |
page |
The page of return.pdf the line is on. |
note |
Anything a reader needs that the other columns do not say. |
The four values of how:
how |
Meaning | from holds |
|---|---|---|
document |
Copied from a source document. | One or more document references: w2#1 is box 1 of the document w2, and 1099b.p2#1d is box 1d on page 2 of 1099b. |
carried |
The same figure as another line. | That line, written FORM:line, for example SD:16. |
computed |
Arithmetic on other lines. | A formula, for example 1040:11b - 1040:14 or round(8959:6 * 0.009). |
law |
An amount or method fixed by law or by the form’s instructions. | Nothing. The note says what fixes it. |
Formulas use line references, numbers, + - * /, brackets, and three functions: min(), max() and round(). round() rounds to the nearest whole dollar.
Three rows from the sample:
form,line,label,amount,how,from,decision,page,note
1040,1a,"Wages from Form W-2, box 1",215216,document,w2#1,W1,1,Includes the restricted stock income shown in box 14
8959,7,Additional Medicare Tax on wages,348,computed,round(8959:6 * 0.009),W4,11,
IL1040,10a,Exemption for the taxpayer,2850,law,,W5,13,"Illinois exemption for 2025, allowed because federal adjusted gross income is not over 250,000"
key/workpaper.md
The decisions behind the return. Each one is a heading and eight fields:
## W2. A wash sale moves the loss; it does not erase it
- Question: 150 shares were sold at a $645 loss on August 20, and new shares of the same stock vested on September 15. Is the loss allowed?
- What we did: Reported the sale on Form 8949 with code W and a $645 adjustment, so that sale shows no gain and no loss.
- Why: ...
- Authority: IRC 1091(a) and (d); Instructions for Form 8949, code W
- Effect: Claiming the loss would cut short-term gain from $928 to $283.
- Shown on: Form 8949 Part I, Schedule D line 7
- Narrative: N6, N7
- Lines: 8949:I.r1.g, 8949:I.r1.h, SD:7, 1040:7a
- Decisions are numbered
W1,W2and so on. Effectsays what the decision is worth, usually in dollars. A grader can use it to weight mistakes.NarrativeandLinestie the decision to the passages it rests on and the lines it changes.
After the decisions come two plain lists. Carried forward holds anything this return creates for a later year. Conventions holds choices that apply to the whole return, such as rounding.
How the parts connect
A passage of the narrative has a source. A decision rests on passages and changes lines. A line names its source: a document, another line, a formula or the law. Starting from any figure on the return, you can walk back to the paper it came from.
IDs
Every case has one permanent ID, a random UUID that we assign when the case is created. It never changes and is never reused. The short form is its first 8 characters.
Any other ID for the same case is a reference. If you number your tasks your own way, tell us the numbers. We store them against our IDs, name your folders with them, and put them in case.json under references. Either ID finds the same case.
Checking a case file
A case file can be checked by a script, with no tax knowledge. The check confirms that:
- the files on disk match the sizes and checksums in
case.json; - every passage of the narrative has a source that exists, and every document is named by at least one passage;
- every
documentline points at a document, and a page, that exists; - every
carriedline equals the line it is carried from; - every
computedline equals its formula; - every
lawline has a note; - every decision points at passages and lines that exist, and is named by at least one line.
The script that checks the sample is in this site’s source code.
Sample copies
In a case sent as a sample, identifying numbers are blacked out on the documents and the return, and left out of the narrative: the taxpayer’s Social Security number, phone number and email address, the employer and payer identification numbers, and state ID numbers. case.json lists them under redacted. A case delivered under contract has them in place.

