Repository navigation
Fix what the second pre-release hand test of dev found - #2577
Merged
Merged
Conversation
…ox never overwrites it Reopening a conversation from Home after Ctrl+C on the engine road showed an empty composer although the draft had been written to disk: the cold beside-open restored the saved draft only over a shared handle (a.shared), which engine conversations no longer use. Worse, the empty composer then saved over the person's words. A cold open now restores the saved draft on every road, and a composer that never loaded the saved draft cannot write over it; a person who clears their own draft still can. v0.8.2 had the restore half of this too. Found by the second pre-release hand test (F-1.q4). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…n the worker Continuing a remote task's parent conversation on the computer that ran the task rebuilt the parent's usage under the parent's id, and could not see that the same calls were already on that computer's ledger under the worker's sessions, so the task was billed twice there. Paid calls now carry a portable identity from the worker through the remote record into the arriving conversation, and reconstruction - here and for R8's folded usage alike - never writes a ledger row for a call the ledger already holds; genuinely new spend still lands once. Found by the second pre-release hand test (F-6.q2). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…rns notice still shows #2567's notice for turns typed in an older codeaf compares the original against a stamp in the copy's copy-ready marker, but a take-back or a materialize rewrote that marker empty, so after a round trip the notice went silent and the rolled-back turns were hidden again with no word. Every writer of copy-ready now carries the existing stamp forward. Found by the second pre-release hand test (F-6b.k round trip). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
#2567 made auxiliary bills owe the conversation's spend stamp, but a late provider receipt banked through reconciliation still did not, so Home's card stayed below /cost by exactly those receipts. The reconciliation path now owes the same stamp. Found by the second pre-release hand test (F-5.k1 remainder). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Since #1893 folded routine endings into background work, a landing whose change could not merge into the checkout was folded too, and nothing on screen named the branch the finished work was kept on - only the journal had it. A landing with unlanded changes now stays visible and says 'branch kept · <branch>', as tasks.md promises; a routine landed ending stays quiet. Found by TestTUIE2E in the second pre-release hand test. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
TestTUIE2E had not been run on a release candidate, and three of its needles waited for presentations the product deliberately changed: - The memory place's tab word is `Memory`: #1830 named it `Memories` and #1943 set it back when the knowledge vault moved in, without updating the needle. The needle, the command catalogue's "Memory tab" lines and the manual pages now all say `Memory` (the /memories command keeps its name). - A first conversation shows #680's starter screen, so the spend test waits for that, not the ordinary greeting's `/task <brief> starts work`. - Since #1893 routine task endings fold into background work, so the nested accept and refused landing assert the decision receipt and the named row's `done` / `incomplete` state - never bare words model prose could match - and tasks.md no longer promises the old `✓ N tasks done` rollup or a second card. Found by the second pre-release hand test. The word gate's weakness that let the Memory needle go stale is #2572. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ble record is still kept aside The guard that keeps a composer which never loaded the saved draft from writing over it also blocked the person's own actions: after a send the sent words stayed saved and came back in the box, and an unreadable or newer record was no longer kept beside the replacement. Sending, editing and a deliberate clear are now the person's own claim on the composer and always reach the save (and its keep-aside path); only a passive empty write from an unread composer is refused. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…, not stored Stamping call_id onto every local ledger row changed a persisted record older builds read (the compatibility law in TestALocalTaskKeepsItsRunLandingAndRecords). Local rows keep their original schema and the receipt derives UsageCallID from the row's existing, append-only facts; remote rows keep the identity they were transported with. The receipt test now expects that derived id (the UsageCallID decision). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…y ceiling The portable call identity brought it to 17 decisions against 15; its phases move into named helpers with no change to the ceiling or the debt table. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A conflicted notice has an unlanded branch, which the kept-branch decision (517cbbf) now keeps visible on purpose; the no-click-target contract is about routine, merged results, so the fixture merges. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A tip and a settings door still said 'Memories tab' after the tab word returned to Memory (#1943); they, and their manual lines, now match. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
AbirAbbas
marked this pull request as ready for review
November 10, 2026 16:07
AbirAbbas
added a commit
that referenced
this pull request
Nov 10, 2026
One rule now recognises a paid call already in the spending ledger: - session.UsageCallID decides it everywhere, and UsageLine.ChargeID delegates to it. - A carried explicit id wins: CallID, "remote:"+RemoteEvent, or the row ID. - Otherwise dev's eight-field fingerprint decides: At, Session, Model, Role, Calls, Input, Output and USD. - A line with neither is still counted against its session's uncovered rows, as both parents did. A row with no identity is never another call's duplicate. - Two different explicit ids are two calls, even when their fingerprints match. This is app/v3 #2332's take law. PRODUCT BUG fixed (from the earlier landing merge, and also present on app/v3 alone): reopening a chat with no receipts booked its paid turns and folded task spend again. All four TestReopeningFoldedTaskSpendNeverRebillsWorkerCalls variants now pass. Seven contract tests in usage_remerge_contract_test.go pin the rule. Conflicts resolved, keeping both sides: - cellindex/usage.go, cellstore/receipt.go, cellstore/types.go, executor/modelcall.go - session/digest.go, loop.go, task_remote_money.go, usage_identity.go (add/add), usage_ledger.go, usage_receipt_test.go - tui3/commands.go keeps app/v3's slashcat table, and dev's "Memory tab" wording moves into slashcat/catalog.go - manual/chat/settings.md and what-i-remember.md Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
AbirAbbas
added a commit
that referenced
this pull request
Nov 10, 2026
PRODUCT BUG from the dev ace7888 merge. dev #2577 and app/v3 fixed the same defect, a late charge missing from Home's figure, in different places: - dev stamped at the end of every bank; - app/v3 stamped after each late door (reconciled, memory billing, aux usage). Keeping both stamped a turn's own calls as they were banked, and again when the turn sealed. An interrupted turn therefore saved its spend twice (TestLateRecoveredCancellationSavesCumulativeSpendOnce). Now bank stamps every bill that is not a step of a live turn, and nothing else does. The redundant stamps in reconciled and the memory billing are gone. Both laws hold: - TestPostSealChargesStampTheHomeTotal (dev); - TestLateRecoveredCancellationSavesCumulativeSpendOnce (app/v3). Co-Authored-By: Claude Opus 5.5 <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 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.
The second full pre-release hand test, on
dev@b0dfe9702after #2567, drove the real binary against a realmodel in throwaway homes on Linux and macOS. It included the v0.8.2 upgrade, rollbacks and the live tmux suite. This
PR fixes the majors it found. Each fix is its own commit with a test that fails with the fix reverted.
Draft until the hand check of this branch passes. Each finding's exact repro is being redone on a binary built
from this branch.
Majors
overwrite the saved words. The cold open restored the draft only over a shared handle, which engine conversations
no longer use. It now restores on every road, and a composer that never loaded the saved draft can't write over
it. v0.8.2 had the restore half of this too.
now carry a portable identity from the worker through the remote record. Reconstruction never writes a ledger row
for a call the ledger already holds: one rule, covering Fix what the pre-release hand test of dev found #2567's folded-usage case too.
materialize rewrote the copy-ready stamp empty. The stamp is now carried forward.
/costby exactly thatreceipt. The reconciliation path now stamps the conversation's spend.
visible again, and says
branch kept · <branch>.The
UsageCallIDcontract (for the app/v3 re-merge)session.UsageCallID(line UsageLine) string(ininternal/session/usage_identity.go) is the one identity of a paidcall, independent of the computer, folder or parent conversation that later carries it:
CallIDthat a remote record or a cell receipt carries (call_idon the wireand in
cellstoretypes).call_id. Their identity is derived ascall:+ theSHA-256 of
[At (UTC RFC3339Nano), Session, Model, Role, Calls, Input, Output, USD]. That's stable because theledger is append-only: a late reconciliation appends its own row and never edits one. Older rows match without
rewriting.
AtorSessiongives no identity (such a row is never deduped).task_remote_money.go) carriesCallIDbesideRemoteEvent, and dedupes on either.internal/cellindex/usage.goreconstruction skips any call whose identity the ledger already holds, and writesthe rest once. That includes Fix what the pre-release hand test of dev found #2567's folded-usage case.
UsageLedgerLockSuffix).Any other identity layer (for example app/v3's) should unify on this one rule: one function, the same precedence
(an explicit id first, then the content hash), and the same "no identity means no dedupe" behaviour.
Suite and manual
The tmux suite and the manual follow decisions the product already made: the tab word
Memory(#1943), thefirst-conversation starter screen (#680), and folded task endings (#1893). The folded receipts are asserted on the
decision receipt and the named row's state.
Minor findings that aren't fixed here are filed in #2575. The tmux word gate's weakness is #2572.
🤖 Generated with Claude Code