fix(journal): keep prose whole on write, lead with open threads on read - #998
Merged
Conversation
Two defects in the journal store, both of which fail toward looking fine. WRITE. The three journal fields were each split on ";", so a semicolon used as ordinary punctuation fragmented a sentence and stripped its subject. The result reads as a list of terse notes rather than as damage, which is why it survived: nothing looks broken. Measured on a real entry, one field produced seven items, six of which began mid-sentence, and one read in full as "the fix on grip dev is 4d11834e" -- true, unattached, meaningless to the reader it was written for. Splitting now prefers newlines and falls back to semicolons only when the text has none. That is how these fields are actually written -- one item per line -- and it keeps every existing single-line caller working unchanged, so `--done "a; b; c"` behaves exactly as before. A single-line field containing prose semicolons is still ambiguous by construction; the fallback is what preserves the documented CLI convention, and that trade is deliberate. The split also existed in six places across two modules, which is its own latent defect: fixing one path would have left the other mangling prose. It is now one function, called from both. READ. The session-start read is BOUNDED, and it rendered Done, then Decisions, then Next -- so completed work consumed the window before open threads were reached. Ordering is not a matter of taste on a truncated surface; whatever leads is what survives. Open threads now lead. Completed work is recoverable from git and the board; an unrecorded open question is recoverable from nowhere. The unbounded display is reordered to match. Nothing forces it there, but two surfaces that teach different priorities are their own defect, and a human reading a full entry also reads top-down and stops. DOCUMENTATION. The author-facing text said "Semicolon-separated list" in six places -- three in the MCP tool description and three in CLI help -- and after this change that is wrong for the multi-line case and right for the single-line one. A half-true rule is worse than the original defect, because it is confidently wrong in one direction. Both surfaces now state the real behaviour at the point of writing, along with the fact that the session-start read is truncated and leads with next_steps, since that changes how an author composes an entry. The two genuinely semicolon-delimited options elsewhere are left alone. Both witnesses assert what the READER RECEIVES rather than what was written, which is the only form that catches this class -- the same move as verifying a published artifact against what the server serves rather than against what was uploaded. Each is killed by exactly one mutation: reversing the ordering tuple reddens the ordering witness alone, and restoring the semicolon-only split reddens the prose witness alone. Co-Authored-By: Claude <noreply@anthropic.com>
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 subscribe to this conversation on GitHub.
Already have an account?
Sign in.
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.
Ref #997 — closes at promotion
What this fixes
Two defects in the session journal, unrelated in code and identical in character: both fail toward
looking fine.
Write — the three journal fields were each split on
;, so a semicolon used as ordinarypunctuation fragmented a sentence and stripped its subject. Measured on a real entry: one field
produced seven items, six beginning mid-sentence, one reading in full as
the fix is 4d11834e. Theresult reads as terse notes rather than as damage, which is why it survived.
Read —
format_for_session_startis bounded, and it led withDone. Completed work consumedthe window before open threads were reached. Ordering is taste on an unbounded surface and correctness
on a truncated one.
The change
Splitting prefers newlines and falls back to semicolons only when the text has none — how the fields
are actually written, one item per line — so every existing single-line caller works unchanged and
--done "a; b; c"behaves exactly as before. A single-line field containing prose semicolons is stillambiguous by construction; the fallback preserves the documented CLI convention, and that trade is
deliberate.
The split existed in six places across two modules, which is its own latent defect: fixing one path
would have left the other mangling prose. It is now one function called from both.
Open threads now lead the bounded read. The unbounded display is reordered to match — nothing forces it
there, but two surfaces that teach different priorities are their own defect, and a human reading a
full entry also reads top-down and stops.
Witnesses
Both assert what the reader receives, not what was written. That distinction is the whole finding:
asserting the written value passes in both the fixed and broken states, which is how two defects
reached a green suite with no test on either behaviour.
Each mutation kills exactly one witness. The ordering witness also asserts both sections are
present, so it cannot pass by one of them simply being absent. A control witness pins the single-line
semicolon behaviour that existing callers depend on.
Test suite
Delta +4, exactly the four tests added here. The four failures are identical on both sides, live in a
module this change does not touch, and are reported so they are not mistaken for regressions.
Premium boundary
recallis OSS: local journal storage and formatting. No identity, org, or entitlement behaviour.