Skip to content

The run says what was written in it - #608

Merged
felipesauer merged 3 commits into
main-v1from
the-run-says-what-was-written-in-it
Sep 9, 2026
Merged

The run says what was written in it#608
felipesauer merged 3 commits into
main-v1from
the-run-says-what-was-written-in-it

Conversation

@felipesauer

Copy link
Copy Markdown
Owner

Every read that reported a run reported the container: an id, a goal, and two durations. lastFactAt says WHEN the last fact landed and can never say WHAT landed, so a session that recorded a decision and one that recorded a passing note reported identically.

What changed

The run projection folds wrote off the same pass and the same envelope slot that already produced lastFactAt — one {kind, count} entry per sort of fact pinned to the run, commonest first, ties broken by the kind's own spelling so the order is total and the array can be compared byte for byte.

It is always present: [] is the answer for a run that wrote nothing, which is a different claim from the absent lastFactAt beside it. An absent field is read as "I do not know"; the fold does know, and says so with a list of length zero.

A count per kind rather than a list of names, and that is a declared divergence from the opening context's convention. Those lists are over entities, which a record holds without limit, so they are cut and the cut declares itself. This one is over the event catalog — a closed union — so it is bounded whatever the run did and needs no cut. The reasoning is written in the type, as the other lists write theirs.

Where it reaches

  • mnema resume / mnema status — through lastRunPhrase, on an open or ended run (the durations only ride an open one, and the reader of an ended run is exactly the person asking "where was I")
  • mnema focus — through the same wroteSuffix, so the two readings cannot word it differently
  • All three --json payloads, and every MCP tool that reports a run, whose description now says what the field is and what an empty array means
  • mnema usage is deliberately left alone: it answers what a session COST, joined to the host's transcripts, and its own closing statement says those numbers are not the record's

Proof

13 mutations and 3 controls, in the foreground; no row reads zero. Two of them found real holes and both are closed here: focus printed the clause with nothing holding it, and the tool description was guarded for naming the field while the sentence around the name was free to say the opposite.

build 0 · lint 0 · 4426 tests (+13), over a dist rebuilt from scratch.

What this does not settle

The opening read is a tool an agent has to ask for, and this was not measured against an agent. The CLI's status reads the same derivation, so a person curating the record reaches it today; which door an agent comes in through is still open.

Every read that reported a run reported the container: an id, a goal, and two
durations. `lastFactAt` says WHEN the last fact landed and can never say WHAT
landed, so a session that recorded a decision and one that recorded a passing
note reported identically.

The run projection now folds `wrote` off the same pass and the same envelope
slot — one `{kind, count}` entry per sort of fact pinned to the run, commonest
first, ties broken by the kind's own spelling so the order is total. It is
always present: `[]` is the answer for a run that wrote nothing, which is a
different claim from the absent `lastFactAt` beside it.

A count per kind rather than a list of names, and that is a declared divergence
from the opening context's convention: those lists are over entities, which a
record holds without limit, so they are cut and the cut declares itself; this
one is over the event catalog, a closed union, so it is bounded whatever the
run did and needs no cut.

It reaches the reader: `resume` and `status` through `lastRunPhrase`, `focus`
through the same `wroteSuffix`, both `--json` payloads, and the MCP run
contract every read that lists a run appends. `mnema usage` is left alone —
it answers what a session COST, joined to the host's transcripts, and what a
run wrote is the record's.
The battery lit every guard of the fold and the store, and left two rows at
zero.

`focus` prints the clause and nothing held it: the only fixture that reached
that line was a run that had written nothing, so handing the wording function
an empty tally changed no byte anywhere. The case now runs two open runs — one
that recorded work, one that recorded none — and reads both lines.

The MCP contract sentence was the other: an agent learns a field exists from
the tool description and nothing pinned it, so falsifying it left the suite
green. The new case reads `tools/list` and states the rule as an implication —
a tool that describes the asker-relative fields of a run is one whose answer
carries a run, so it must describe `wrote` too. A fifth tool appending the
same contract is covered the day it is written.
A tool description that names `wrote` while saying it is on NO run reported is
worse than one that omits it, and the guard could not tell the two apart: it
asserted that the field is mentioned. That mutation was the only row of the
battery still reading zero once the instrument was fixed.

The claim is asserted now — the scope, the name, and what an empty tally
means — and the battery carries one row per claim, because a guard over one of
three is not a guard over the other two.
@felipesauer
felipesauer merged commit 30f031a into main-v1 Sep 9, 2026
4 checks passed
@felipesauer
felipesauer deleted the the-run-says-what-was-written-in-it branch September 9, 2026 00:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant