The To-do destination: routed tasks land on a list the walker can work (#160) - #165
Merged
Conversation
#160) route = "todo" Threads get their real surface (docs/desk.md, D2): /todo lists them as checkable items in the walker's own words — the first Capture's text, never the Enrichment's title. Checking one off is an action on the destination (todoDoneAt on its own seam, /api/sync/todo); it never reopens or re-files the Thread, and it survives reload and hydrates across devices like the review decision does. Un-routing at the desk removes the item by construction — the list is fed by the route, not a copy. The day digest checklist now draws from that day's routed to-dos instead of re-deriving tasks: the client sends them with every ask, the prompt carries them verbatim, and the system instruction makes them the checklist when present. Closes #160 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KPox3By2txjxSy8HUAPVKk
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Mechanical refresh from the skills sync tooling at session start: updated vendored copies under .agents/skills and their computed hashes in skills-lock.json. No product code touched. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KPox3By2txjxSy8HUAPVKk
…on-160 # Conflicts: # app/globals.css # lib/local-capture/types.ts # lib/sync/hydrate.ts # lib/sync/memory-repository.ts # lib/sync/neon-repository.ts # lib/sync/types.ts
…on-160 # Conflicts: # components/desk-workspace.tsx
wschenk
pushed a commit
that referenced
this pull request
Aug 8, 2026
#165 landed, so the To-do row's "Landing next" pill is now false. It reads Live, points at /todo, and says the thing worth knowing about that surface — ticking an item off is the list's own business and never re-files the Thread. The setup section drops the caveat it no longer has. The status pills are the one part of the legend that is hand-held rather than derived, which is exactly why they need this pass every time a destination ships. No-ticket: true Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Mm4zPLAX77USAqyk12jgc1
2 tasks
wschenk
added a commit
that referenced
this pull request
Aug 8, 2026
#165 landed, so the To-do row's "Landing next" pill was false. It reads Live, links /todo, and says the thing worth knowing about that surface — ticking an item off is the list's own business and never re-files the Thread. The setup section drops the caveat it no longer has. The status pills are the only hand-held part of the legend; the rest derives from THREAD_ROUTES and routeForKind. That is why they need a pass whenever a destination ships. The one remaining hand-held claim is Spec's "Needs a token". No-ticket: true
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
route = "todo"Threads get their real destination (docs/desk.md, slice D2):/todosurface (linked from the Days header) lists every Thread routed to To-do as a checkable item in the walker's own words: the first Capture's text, never the Enrichment's title. It re-reads after each sync cycle, so a to-do routed on another device lands live.todoDoneAtfield rides its own seam (POST /api/sync/todo→ThreadRepository.setThreadTodoDone) and deliberately never touchesreviewedAtorroute, so checking an item off cannot reopen or re-file the Thread. It persists in the local store (IndexedDB), round-trips through the memory and Neon repositories (todo_done_atcolumn), and hydrates across devices inmergeRemoteThreadsthe way the review decision does.buildDayDigestPromptcarries them verbatim (- [ ]/- [x]), andDAY_DIGEST_SYSTEM_INSTRUCTIONmakes them the checklist when the section is present — deriving from reports only for callers that predate the field.route = "todo"itself, not a copy, so clearing or redirecting the route at the desk takes the item off the list. This composes with the Day flow'sunfileThread(The default door: a Day with unrouted Threads opens on the arrival summary (#159) #168), which clears the route.Closes #160
Merged with main (
662a5cc)This branch was last of the five-way fan-out, so it carries a merge of
mainat84875ab(after #167 timeline, #166 journal, #169 spec routing, #168 day flow). Six files conflicted and every one was resolved by keeping both sides' additions — no sibling's work was dropped:lib/local-capture/types.tstodoDoneAt+specHandoffonLocalThreadandapplyRemoteThreadslib/sync/types.tsServerThread;setThreadTodoDone+recordSpecHandoffboth on the repository interfacelib/sync/hydrate.tsmergeRemoteThreadslib/sync/memory-repository.tsStoredThreadand thelistThreadsmappinglib/sync/neon-repository.tsADD COLUMNmigrations), both in the SELECT, the row type, and the mappingapp/globals.cssNote for whoever merges this file next:
lib/sync/hydrate.tscontains a literal NUL byte in ajoin()separator, so git classifies it as binary, refuses to merge it, and keeps one side wholesale with no conflict markers. Trusting "no markers = resolved" here would silently drop the other side's field from the adopt-list while still compiling. This merge diffed both sides and reapplied the additions byte-wise, preserving the NULs. Replacing that separator with an ordinary string is worth a follow-up.Test plan
tests/todo-destination.spec.ts(memory repositories / pure seams): routing to To-do lists the walker's words; check-off round-trips without re-filing;todoDoneAthydrates both ways; un-routing and redirecting remove the item; the digest prompt and system instruction carry routed to-dos, with absence keeping the old derive behavior.tests/todo-destination-ui.spec.ts(public browser seam,thread-filing-uipattern): route via the desk filing UI → item appears on/todoin the walker's words → check-off sticks across reload → the day still reads "All filed" → un-routing empties the list; the day-digest ask POSTsroutedTodosfor that day.pnpm exec tsc --noEmitclean; eslint clean on every changed file; 48 passed / 1 skipped / 0 failed acrosstodo-destination,todo-destination-ui,thread-filing,thread-filing-ui,day-flow,sync-hydrate,sync-repository,day-digest,day-digest-ui. (The skip is the Clerk setup project, which skips without preview keys.)routedTodossurvives end to end.