Holding a goal outside your head
I built a goal tracker and deleted its best feature thirty-eight minutes later. Anything that scores your own goals gets optimised against, including by you.
Motivation
Write down a goal and you have made an object that begins going out of date immediately. The goal itself may be perfectly stable, but everything around it moves: what you have tried, what you learned, how far away you are. So the note you wrote in January is still legible in March and no longer tells you anything, because the part that was useful was never the words. It was the distance between the words and where you actually are.
The usual fix is to keep the note updated, which fails for the ordinary reason that updating it is work nobody does. The second fix is to have software keep a status on it, which is what I built one afternoon in August, and which failed differently and more interestingly.
First version: the live verdict
I built the goal as a file with a live reading attached to it. Each goal was a set point, each set point carried the last verdict computed against it, and a command recomputed the verdict on demand. It is the obvious design. It is also the design behind every stale STATUS.md, and behind the focus widget I had already built and already stopped trusting.
By early afternoon I had written down the reframe that replaced it: rather than keeping a live object, my entire history is just recomputed to answer the question of how far I am from my goals, what I have been doing for them, and what I should be trying next.
The difference between those two designs is small to describe and total in effect. A stored verdict is a claim about the past that keeps presenting itself in the present tense. It was true when it was written, it is silently wrong now, and nothing about looking at it tells you which. A recomputed report cannot be stale, because it does not exist between runs. You ask the question, it reads the record as it stands, and it answers. Then it stops existing.
Thirty-eight minutes separated building the live object from killing it, and the only reason I caught it that fast is that I had been burned by exactly this twice before and finally recognised the shape.
Status as directory
What replaced the live reading is smaller than what it replaced.
macrostates/
active/ fulfilled/ retired/ reports/
A goal is a markdown file. Its status is the directory it sits in, so changing the status means moving the file, and there is no status field anywhere to disagree with the location. Reports are timestamped folds: each run rereads the logs, the journals and the worklogs, computes the answer fresh, and writes a dated document into reports/. Nothing derived is ever stored on the goal itself.
The failure this is built against is worth naming exactly, because it is not laziness. Monday-me writes down what the week is for. Thursday-me has no pointer to it. Both of those people are paying attention and the intention simply does not survive the gap, because it was stored in a state that ended. The folder is the pointer. The agent reading it is the fold.
The schema defect
The instrument found its own worst defect before reality did, which is the part of this I am most pleased about.
The first report ran as a folder of documents, one agent per goal, and it flagged eight defects in its own verification lines. One of them was a goal that could never read as achieved. I had written the goal, I had written the condition under which it would count as met, and the condition was unsatisfiable in a way that reading it casually would not reveal.
The cause was one level below the mistake. Some of what I wanted about that goal was a genuine requirement, and some of it was a preference: not that the goal must be achieved this way, but that I would rather it were. The schema had a field for conditions and no field for preferences. So the preference went into the conditions field, because that was the only place it fit, and the system then did exactly what it was told and treated a nice-to-have as a requirement. Reported honestly, a goal I could actually reach would have come back as failed.
The rule I wrote down is that edges relate, they never condition. Two goals can point at each other to mean load this one when you are reading that one, and that is all such a link is allowed to mean. It never means one gates the other. Alongside it the schema got the field it was missing.
Here is what a goal file is, after the fix. The frontmatter carries the machine-readable parts, and the body is a fixed set of sections:
---
kind: center
priority: 1
review_with: <other-slug>
created: 2026-08-18
updated: 2026-08-18
verify: <the one line that reads true or false>
---
## Motivation
## Fulfilled when
## Preferences (not conditions)
## Evidence
## Counter-evidence
## Refinements
## Plan
verify is the condition and it is a single line, which is deliberate, because a condition you cannot state in one line is usually two conditions with a preference wedged between them. Preferences (not conditions) is the section that did not exist on the morning this broke, and the parenthesis in its name is doing real work: it is there so that nobody, including me, files a nice-to-have one heading higher.
The links are in the frontmatter too, as review_with, parent and constrained_by, and all three mean the same thing. Load that one when you read this one. None of them gate.
The general form is the useful part, and it is not about goals. A value with no home in your schema does not disappear. It moves into the nearest field that will accept it, and then behaves as that field's type. Nothing errors. The data structure looks fine. The system draws a confident wrong conclusion, and the defect is invisible at the level where it hurts, because at that level everything is correctly typed and correctly evaluated.
Adjudication
Between the morning and the evening I had also built the machinery you would expect around all this: a file of stored verdicts, a hash of each goal's condition so you could tell when a condition had been edited, ordinal rungs so progress could be ranked, a command that printed the delta between readings, and a field for the time horizon.
I tore all five out the same day.
What is left is a rule: no script computes a verdict, and scripts only gather material into a context window. The whole command surface is that rule made concrete:
organs macrostates tree # the goals, by priority, with their hierarchy
organs macrostates review <slug> # what to load when reading this one
organs macrostates lint # broken links, cycles, duplicate lanes
organs macrostates context --reports 2 # two eras in one window
organs macrostates report new # mint reports/<timestamp>/
Not one of those returns a judgment. tree prints files, review prints the set of documents to read alongside a goal, lint checks the structure rather than the substance, and context puts two reports side by side and leaves the comparing to whoever is looking. The commands exist to put the right documents in front of a reader, and the reader does the adjudicating. Convergence, meaning the question of whether anything is actually moving, is answered by loading two eras side by side and reading them, rather than by diffing a number that two different schemas produced.
I want to be precise about why, because "let the AI decide" is not the reason and would be a bad one. A verdict is a judgment about whether a piece of evidence counts, and judgments about your own goals are exactly the judgments you will bend. Any number the system produces becomes a number you can move without moving your life, and you will, and it will not feel like cheating at the time. Removing the number removes the affordance. There is nothing to optimise except the thing itself.
The same session added the caveat that keeps the instrument honest: it reads what I logged, not live sensors, so a gap in the record is a missing datapoint and never a negative finding. An instrument that cannot tell silence from a bad result will manufacture bad results out of quiet weeks.
The naming constraint
A week later I read a report about my own goals and could not follow it. The names had been abstracted into a system's vocabulary, and one of them had been generalised to the point where I no longer recognised what I had asked for. My correction at the time was that the goal should literally be the number I actually want, not a tidy phrase describing the category of thing it belongs to.
That is a constraint on any system that holds your intentions for you. The abstraction reads as more general and is in fact less true, and the version you will recognise at midnight when you have forgotten what you are doing is the one written in the words you would have used out loud. Compression is the enemy here. There is exactly one reader, and the whole value is that they recognise the thing instantly.
What the organ is, after all of that, is not a tracker. It is a way of getting the right material into one window so a question can be answered from scratch. The goals are files, the history is the record I already keep, and the only computed thing in the system is the answer, and it is written as a dated document rather than folded back onto the goal.