Sync settle inbox and reconcile subthread sidebar#239
Conversation
…cle (pingdotgg#4026) Co-authored-by: Claude Fable 5 <noreply@anthropic.com> Co-authored-by: maria-rcks <maria@kuuro.net>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a45e7b2ff8
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6126e99d2f
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: de2084ba57
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| if ( | ||
| supportsSettlement && | ||
| effectiveSettled(thread, { now, autoSettleAfterDays, changeRequestState }) | ||
| ) { | ||
| settled.push(thread); |
There was a problem hiding this comment.
Keep mobile v2 subthreads grouped through settlement
When a mobile v2 list contains a mixed subthread tree, such as a settled parent with an active child, this per-thread partition pushes the settled member into the global settled tail and leaves the active member in the card block. Both HomeScreen and the split sidebar call this builder, so subagent children can be detached from their parent context on mobile even though the web v2 path keeps a tree in the inbox until every member settles; the final code here still partitions each shell independently. Build the mobile list from the parent/child tree before splitting settled groups.
Useful? React with 👍 / 👎.
| const visibleSettled = | ||
| orderedSettled.length > settledLimit ? orderedSettled.slice(0, settledLimit) : orderedSettled; |
There was a problem hiding this comment.
Keep the selected settled row visible on mobile
When the currently open thread is a settled row beyond the first settled page (for example on iPad/split after the page resets to the first 10), this slice drops it from items completely. ThreadNavigationSidebar can only apply its selectedThreadKey to rows returned by this builder, so the sidebar can show no current thread while that chat remains open; the web v2 pager explicitly keeps the active settled group visible for this case. Pass the selected thread key into the mobile builder and include that settled row despite the page limit.
Useful? React with 👍 / 👎.
| // Server-side twin of the client's canSettle session check: a stale | ||
| // or raced client must not settle a thread whose session is coming | ||
| // alive or working. | ||
| if (hasActiveThreadSession(thread.session)) { |
There was a problem hiding this comment.
Block settling turns already marked running
When an assistant stream materializes latestTurn.state === "running" before the matching thread.session-set has reached the read model, this session-only guard still accepts thread.settle. The projector and sidebar sort logic already treat a running latest turn as active work, so a stale/raced client can hide an in-progress response until some later session activity happens to un-settle it; reject running latestTurn here and mirror that in the client settlement blockers.
Useful? React with 👍 / 👎.
Design recommendation — independently settled subthreads, visually grouped
Adam deliberately withheld his preference, so this recommendation is based on workflow merits and is intentionally easy to redirect before approval.
Recommendation implemented: B. Each row owns its settled state. A parent tree stays in the active inbox while any member is unsettled; settled members become slim rows in place; the parent reports its open-descendant count; only a fully settled tree moves as a group into the history tail. This lets completed workers clear independently while preserving parent context.
What this PR brings in
055to add nullable settlement state. Existing rows remain intact and decode as unsettled; no historical thread is silently moved out of the inbox.Ephemeral UI proof
Captured against an ephemeral server using a SQLite
.backupcopy of the live state DB plus new synthetic parent/child fixtures. The live DB was never opened by the proof server.Verification
Landing policy
Do not auto-merge. This PR requires Adam's manual design approval in addition to the normal CI, Codex review, and wizzo-approve conditions.