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 goes out of date immediately. The goal is stable. What moves is everything around it:
- what you have tried
- what you learned
- how far away you are
The useful part was never the words. It is the distance between the words and where you actually are.
Two fixes, and they fail differently.
- Keep the note updated. Fails for the ordinary reason that updating it is work nobody does.
- Have software keep a status on it. Fails in a more interesting way, and the rest of this is about how.
First version: the live verdict
The first design makes the goal a file with a live reading attached. Each goal is a set point, each
set point carries the last verdict computed against it, and a command recomputes the verdict on
demand. It is the obvious design, and the design behind every stale STATUS.md, and behind the
focus widget it replaced.
The reframe that kills it: rather than keeping a live object, the entire history is recomputed to answer how far the goal is, what has been done toward it, and what to try next. The difference 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. True when it was written, 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, it answers, and then it stops existing.
Thirty-eight minutes separate building the live object from killing it, which is how long a stored verdict takes to show what it is once the one you are reading is your own.
Status as directory
What replaces 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 status means moving
the file, and there is no status field anywhere to disagree with the location. Reports are folds
carrying their own date: each run rereads the logs, the journals and the worklogs, computes the
answer fresh, and writes a dated document into reports/. Nothing derived is stored on the goal
itself.
The failure this is built against is not laziness. Monday-me writes down what the week is for. Thursday-me has no pointer to it. Both are paying attention, and the intention 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 finds its own worst defect before reality does. The first report runs as a folder of documents, one agent per goal, and flags eight defects in its own verification lines. One is a goal that can never read as achieved: the goal and the condition under which it counts as met are both written down, and the condition is unsatisfiable in a way a casual reading does not reveal.
The cause sits one level below the mistake:
- A goal mixes requirements with preferences, where a preference is not that it must be achieved this way but that it would be better if it were.
- The schema has a field for conditions and none for preferences.
- The preference goes into the conditions field, because that is the only place it fits.
- The system does exactly what it was told and treats a nice-to-have as a requirement.
- Reported honestly, a reachable goal comes back as failed.
The rule that follows is that edges relate, they never condition. Two goals can point at each other to mean load this one when you read that one, and that is all such a link is allowed to mean. Alongside it the schema gets the field it was missing.
A goal file after the fix. Frontmatter carries the machine-readable parts, 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
verifyis the condition and it is a single line, deliberately, 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 when 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.review_with,parentandconstrained_byall mean the same thing. Load that one when you read this one. None of them gate.
The general form 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, and the system draws a confident wrong conclusion, because at the level where it hurts everything is correctly typed and correctly evaluated.
Adjudication
The machinery you would expect around all this got built alongside it.
| mechanism | what it was for |
|---|---|
| a file of stored verdicts | keeping the last reading attached to the goal |
| a hash of each goal's condition | detecting that a condition had been edited since a reading |
| ordinal rungs | ranking progress |
| a delta command | printing the change between two readings |
| a time-horizon field | carrying when the goal was expected to land |
All five came out in one correction, under one rule: no script computes a verdict, and scripts only gather material into a context window. The rule reaches the verdicts file and the rungs directly, because both are computed judgments. The hash and the delta command have no function once verdicts are not stored, since one detects that a stored reading is out of date and the other compares two of them. The horizon field went with them.
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 returns a judgment. The commands put the right documents in front of a reader and the reader adjudicates. Convergence, meaning 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.
A verdict is a judgment about whether a piece of evidence counts, and judgments about your own goals are the ones you bend. Any number the system produces is a number you can move without moving your life. Removing the number removes the affordance, leaving nothing to optimise except the thing itself.
One caveat keeps the instrument honest: it reads what was 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 report becomes unreadable to its own author when the names in it are abstracted into a system's vocabulary. Generalise a goal far enough and the person who wrote it no longer recognises what they asked for. The correction is that the goal should literally be the number actually wanted, 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 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.
The organ 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 already being kept, and the only computed thing is the answer, written as a dated document rather than folded back onto the goal.