The run says what was written in it - #608
Merged
Merged
Conversation
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Every read that reported a run reported the container: an id, a goal, and two durations.
lastFactAtsays 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
wroteoff the same pass and the same envelope slot that already producedlastFactAt— 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 absentlastFactAtbeside 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— throughlastRunPhrase, 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 samewroteSuffix, so the two readings cannot word it differently--jsonpayloads, and every MCP tool that reports a run, whose description now says what the field is and what an empty array meansmnema usageis 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'sProof
13 mutations and 3 controls, in the foreground; no row reads zero. Two of them found real holes and both are closed here:
focusprinted 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 adistrebuilt 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
statusreads the same derivation, so a person curating the record reaches it today; which door an agent comes in through is still open.