A Log You Can Ask — What Thirty Notebooks Could Not Show

9 min
GoalIn 2026-04 we ran a piece about a farmer moving thirty years of handwritten notebooks onto one screen. At the heart of that piece — "say it and it becomes a screen" — there was nothing real. We constructed the situation to its real shape and built the whole thing ourselves — and "eighteen days" appears nowhere in the source. It is computed from the records.

Something to state up front. In April 2026 this magazine ran a piece about a thirty-year tomato grower in Oregon, who moved thirty notebooks from a barn onto one screen. It was an interview naming the person, their age and their region.

This is not a specific farm. So we do not republish that interview. Instead we built the same shape from beginning to end ourselves. Every screen and every number below comes from what we built, and it is not any one farm's records.

The reason this distinction sits in the first paragraph is that the original's whole argument is permission — "you can do this too" — and that permission rests on the reality of the case. Repeating the same sentence without having confirmed that reality is not permission, it is advertising.

So what this piece sets out to prove narrows. Not "a farmer did it" but "a tool like this looks like this, and it really does this much".

The heart of the original had nothing real in it

The original's axis was good. Paper stops at writing. Taking things out and comparing them is left to human memory and patience. But stacked in the same slots, a record becomes something you can ask.

We still think that shift in materiality is right. The problem is that the piece never once showed it.

  • What he actually said — zero lines of the original request
  • What screen definition that speech became — zero lines of definition
  • What steps it went through — zero steps of process
  • Moving thirty notebooks — only the statement "I'm transferring them bit by bit"

And the piece's best line — "first flower on day eighteen after transplanting" — was the same. It is a claim that only stands once five seasons of data exist, and neither that data nor the screen where it emerged was there.

This time we put three things side by side. What was said → what became a definition → what was actually drawn.

What was said

While building, we wrote the requirement as three sentences. No development vocabulary.

  1. "Pick a crop and this season's records come up in a row."
  2. "Recording should work with one hand."
  3. "Show me what this time last year looked like, next to it."

Three sentences became three tools.

log offers: log.season, log.add, log.compare

What became a definition

The first sentence became this part of the screen. Not code — a declaration.

{
  "type": "list",
  "items": "{{season}}",
  "emptyMessage": "Nothing recorded this season yet",
  "itemTemplate": {
    "type": "linear", "direction": "horizontal", "spacing": 12,
    "children": [
      { "type": "text", "text": "{{item.date}}" },
      { "type": "text", "text": "{{item.action}}" },
      { "type": "text", "text": "{{item.tempC}}°C" },
      { "type": "text", "text": "{{item.note}}" }
    ]
  }
}

The second sentence became one button.

{
  "type": "button",
  "label": "First flower",
  "onTap": {
    "type": "tool", "tool": "log.add",
    "params": { "crop": "Tomato", "action": "firstFlower", "tempC": 19.5 }
  }
}

The third sentence produced one more screen. One line of route.

"routes": { "/": "ui://pages/today", "/compare": "ui://pages/compare" }

The whole app is four JSON files. No compiler runs.

What was actually drawn

Today's screen. Days since transplanting and the average of past years sit at the top.

This season — every line carries the temperature it was written at. Real render capture

Press "First flower" once and one row appears.

One tap adds one line — 2026-04-19 firstFlower recorded

And the screen with the years laid over each other.

Season against season — transplant to first flower, 2021:22d through 2026:18d. The 18.2 d average is counted from this list

18.2 days is written down nowhere

This is the most important part of this piece.

The original wrote "eighteen days" as though it were a result. In this sample that number is not a constant. It is computed from the records every time.

/// Days from transplant to first flower, per season.
///
/// This is the whole "eighteen days" claim, and it is arithmetic over the
/// rows — no constant anywhere. A year with no flower recorded yet is left
/// out rather than guessed at.

And the verification confirms that directly. If the computed value appears as a string in the source, it fails.

src = open(os.path.join(SERVER, "bin", "server.dart")).read()
assert str(cmp["avgDays"]) not in src, "the average must come from the records, not the source"

The passing log.

   average 18.2 computed from records, not present in any source file

"It emerged from the records" and "somebody typed it in" look identical on screen. So a way to tell them apart went into the pass condition.

The exceptions start to speak

The best observation in the original was not the average but what came after it. Once there is an anchor, the years that depart start to become visible.

The computed table is exactly that.

spans: 2021:22d, 2022:18d, 2023:15d, 2024:18d, 2025:18d, 2026:18d

2021 was twenty-two days, and that row's note carries five cold days in early April. 2023 was fifteen days, with warm week before transplanting.

In scattered notes, both twenty-two and fifteen would have drifted past as "a bit different this year". With no baseline to compare against, you do not even know they are exceptions. Only once the average of 18.2 stands do those two years start to speak.

Without the same slots, nothing stacks

There is one condition under which all of this holds. The records have to be the same shape.

/// One entry, in the same six slots every time. The whole argument of the
/// article rests on this being fixed: `plot · crop · action · date · note ·
/// tempC`. Paper let every year invent its own shorthand; slots do not.

Six slots. This is what paper could not do — paper allows a different shorthand every year. Whether 2019's "set out" and 2023's "moved" mean the same thing, the notebook does not know.

And one thing was done deliberately about the date.

// The date is the machine's, not the grower's memory. Paper let a row
// be written three days late with no trace; this cannot.

The division between judgment and tool

The original's best asset was a five-row table dividing the work. Judging what needs recording is the farmer's; carrying it is the tool's. We keep that table, and this time each row points at something real seen above.

What Who The real thing in this piece
Deciding what to record Farmer Six slots (plot·crop·action·date·note·tempC)
Saying how you want to see it Farmer Three sentences of requirement
Turning that speech into a screen Tool Four bundle JSON files
Stacking, filtering, computing Tool log.season · log.add · log.compare
Deciding what to do Farmer — (the tool does not judge)

The last row is the same place as the original's restrained boundary section. That sentence sits verbatim at the bottom of the screen.

A tendency, not an instruction. Read this season on its own terms.

The tool takes an average; it does not tell you to plant. Cross that line and thirty years of judgment go unused.

The range of this sample

There is no farmer. The three requirement sentences in this piece were written by me, and the five seasons of records were made by me. So please do not read this as "a farmer built it this way". What this piece showed reaches "a tool like this looks like this, is this short, and the average really is computed".

And we did not confirm whether a domain expert can handle this format directly. The JSON above is readable, but whether a fifty-eight-year-old grower could edit it themselves is a separate question and this series did not answer it. The conversion the original called "just say it" — the step where a person's words become a definition — was done here by my hands.

Moving thirty notebooks was not addressed either. How much work it really is to move paper into slots was not measured by this sample.

We also note why the UI is in English. The samples in this series use English on screen and in the code. This piece is a construction rather than any one farm's tool, so a reader in any language reads the same capture and the same source.

From writing down to asking

The original closed with "start small and add one slot at a time". We keep that advice.

To it we add one line learned from building. Keeping the slots the same is harder than adding slots. Deciding the six slots took under ten minutes, but those six have to stay the same across five seasons for the final screen to hold. That is exactly where paper failed.

And once it holds, the record changes its nature. From something written down to something you can ask. 18.2 days was not written for us by anybody; it was the answer to a question.

Practice task

Pick one answer from the plant example and name the record it cites. What would the tool do if no record matched?

Related articleA Log You Can Ask — What Thirty Notebooks Could Not Show