Repository navigation
perf(server): t3_task_read returns only changed tasks after a cursor - #178
Merged
Merged
Conversation
Captains call t3_task_read with no threadId on every wake and get every task they own in full. The read now takes an optional afterCursor and returns only tasks changed since then, plus the new cursor. A task that moves to another owner is recorded as a departure under the move's cursor and comes back in `removed`, so a delta reader drops it. Settlement already bumps the cursor. t3_task_watch uses the same visibility and cursor logic, so it reports departures too. Without afterCursor the read is the full list, as before. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Thread transfer impact✅ Thread transfer remains within every enforced ceiling.
Baseline: Scenario and decoded snapshot size10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.
Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed. |
jayleaton
marked this pull request as ready for review
October 31, 2026 03:17
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.
Summary
Captains call
t3_task_readwith nothreadIdon every wake, and each call returns every task they own in full. The read now takes an optionalafterCursor:ThreadTaskStore.putnow records that move in a newthread_task_departurestable (fork migration 14) under the move's cursor, in the same transaction as the write. If the task later returns to that owner, the departure row is deleted.readandt3_task_watchnow share one function,visibleChanges. As a result, watch also reportsremoved. The watch catalog sentence is unchanged; another PR is editing it.put.ThreadTaskReadInput.afterCursor, optionalThreadTaskListResult.removed), the gateway's zod schema, and thet3_task_readdescription.Evidence
t3_task_read { afterCursor }is rejected by the gateway's strict input schema (afterCursoris not a key there), so a Captain has to read every task on every wake.ThreadTaskService.test.tsuses three owned tasks. The full read returns all three. A read after the cursor returns only the one task that changed. A settled task appears withsettlement.state = "settled". A task moved to another owner comes back asremoved: ["gamma"]and is gone from the full read. Moved back, it comes back as a changed task, not as a removal.Typecheck passes for contracts, mcp-gateway, and server;
vp fmt --checkandvp lintpass on the touched files.ForkMigrations.test.ts > keeps upstream's migration ids and namesfails locally only because this machine'supstream/mainref is 6 days stale (69 upstream migrations vs 72 on main). It checks the upstream ledger, which this PR does not touch.No eval covers
t3_task_read's text, so no eval was run.Merge Danger
Door: two-way
The migration only adds a table (
CREATE TABLE IF NOT EXISTS). Reverting leaves it unused.Blast Radius: tasks
Every task write now does one more indexed select inside a transaction. Readers that don't pass
afterCursorget exactly what they got before.🤖 Generated with Claude Code