conduit · Mark unread and Un-settle,
placed in the system

Two verbs the server already has and the UI only half shows. Mark unread has no control anywhere. Un-settle works from the list, but once a session is open it has only a banner that was designed and never built, and auto-settle is about to make that moment common. This page draws four ways to place both verbs, on the phone and the desktop, in the list and inside a session, and ends with one recommendation.

Companion to mobile-first-sidebar.html, whose tokens, rows, sheets and session bar this page reuses unchanged · Phone frames are 340 px wide

0What every direction shares

The four directions differ only where there is a real choice. Everything below holds in all of them, so the comparison at the end is about placement, not about semantics.

How read works today

  • One timestamp, read_at. Switching to a session writes it. session.unread sets it to null. Any message newer than it makes the row unread again.
  • So opening marks read, not viewing: the write happens on arrival. Stay in a session you just marked unread and it stays unread, unless the client re-opens it on a reconnect or reload.
  • There is no Mark read RPC. Undo, and Mark read by hand, both need one.
  • A hand-marked row and a never-opened row are the same row to the server. Telling them apart needs one column.

Rules every direction keeps

  • Paired verbs flip in place. Menus, sheets and keys show whichever half applies: Mark unread or Mark read, Settle or Un-settle.
  • Neither shelf shows read state, so settled and snoozed rows do not offer Mark unread, the same way Snooze disappears on a settled row.
  • The Unread chip counts live rows only. Settled and snoozed never count, as in §2 of the main doc.
  • Sending a message means "I'm back". It un-settles, it wakes, and it ends a hand-set unread.

Where this meets auto-settle

  • An unread session never auto-settles, so Mark unread also means "keep this in front of me". The auto-settle setting should say so in one line: Sessions you haven't read never auto-settle.
  • Un-settling pauses auto-settle until there is new activity.
  • Auto-settle when idle is a per-session checkbox, on by default. It keeps that label, and that polarity, on every surface.
  • Auto-settled rows read Auto · 1d on the shelf.

Copy

  • Verbs as the menu has them: Mark unread, Mark read, Settle, Un-settle, Auto-settle when idle.
  • Banners and toasts are short sentences, one idea each. No em dashes, no "successfully", no exclamation marks.
  • The icons stay as they are: ● unread, ✓ settle, ↶ un-settle, ☾ snooze, ⚑ pin.

AMenus and keys: marking unread takes you back to the list

The smallest change. No new gesture, no new hover icon, no new state to draw. Mark unread goes into the sheet, the menus and the keys that already exist. Inside a session it does what Gmail does: it marks the session and takes you back to the list, so the rule that opening marks read never has to bend.

Inside a sessionMarks unread and leaves. The phone pops to the list; desktop closes the pane and puts the focus ring on the row.
The rowIdentical to Done, unread: same tier, ✓ glyph, Done pill. That is literally what the server now says.
GestureNone. Long press is the touch route, as the §4 table already has it.
Desktop hoverUnchanged: ✓ ☾ ⚑ ⋯. Mark unread is in ⋯ and right-click.
Un-settle when openThe banner from the main doc, above the composer. The auto-settled banner adds a second row with the checkbox.
Keysu and s in the list. ⌘⇧U in a session marks unread and closes.

Rows

Marked unread · same as done, unread
✓Audit brew bundleDFdotfiles · mainDone
Settled, mid-swipe · ↶ on the settle side

Phone

A1 · long pressMark unread stays where it is

The sheet from the main doc, with the auto-settle checkbox added under Settle, where the code already puts it. Mark unread keeps its place in the second group.

On a read row it says Mark unread; on an unread row, Mark read. On a settled row it is not there.

A2 · from the session⋯ says where you'll end up

Bar 18's overflow sheet gains Mark unread in its Session group. The tail says back to the list, because an action that navigates should say so before you tap it.

No hold rule is needed: you are never looking at a session you just marked unread.

A3 · where you landBack on the list, row in Done, unread

The list re-sorts on navigation, so the row has already moved into Done, unread when you arrive. The toast names it and offers Undo, which marks it read again.

The cost is visible here: a session that went idle two days ago now wears a Done pill as if it just finished.

9:41✦ ▮▮▮
Sessions 18⇅⋯
All projects ▾⌕Search
Needs you 1Running 1Unread 2Settled
Marked unread Audit brew bundleUndo
A4 · auto-settled, openedThe banner grows a second row

Same banner as the main doc's frame 11, above the composer. When the server settled it, a second row carries the checkbox, with the menu's own label, so the setting that did this is right there to turn off.

Unchecking it does not un-settle. It only means this session will not be auto-settled again.

9:41✦ ▮▮▮
‹Sessions2COconduit·main⋯
Wire PTY resize ▾
ChatTerminalDiffFiles
Message conduit…

Desktop

‹Sessions2Wire PTY resize ▾·COconduit·main#212 merged
ChatTerminalDiffFiles
⋯
Message conduit…

The sidebar toast is from pressing u on the focused row while another session is open. Toasts sit at the foot of the column the row lives in: the sidebar on desktop, the screen on a phone.

1.  Right-click, as today plus the checkbox
2.  ⌘⇧U in a session closes the pane
No session open↵ reopens the focused row

Desktop behaves like the phone: the pane returns to its empty state and the focus ring sits on the row you left. The list was already on screen, so this is a surprise if you meant to keep reading.

Keys

  • List focused: u marks unread or read, s settles or un-settles.
  • In a session: ⌘⇧U marks unread and closes, Gmail's ⇧U then back. ⌘⇧S settles or un-settles and stays.
  • ⌘Z undoes either for five seconds.

Good

  • Nothing new to learn, draw or test beyond two menu items.
  • No hold rule: you never look at a session you just marked unread.
  • The row shows exactly what the server stores. No new column.

Risky

  • A two-day-old session reappears with a Done pill, as if it had just finished. That misreports what happened.
  • Closing the pane on desktop, where the list is already visible, punishes the person who wanted to keep reading.
  • Mark unread stays item seven of a menu, so its second job, keeping a session from auto-settling, is invisible.

Cost

  • Two menu items, one sheet item, u and ⌘⇧U.
  • A Mark read RPC for Undo.
  • The banner's second row.
About a day. The cheapest by a distance.
ActionTouchPointerKeyAlso
Mark unreadLong press → Mark unread⋯ or right-clicku; ⌘⇧U in a sessionSession ⋯. From a session it returns you to the list
Mark readLong press → Mark read⋯ or right-clickuOpening the session; Undo on the toast
Un-settleSwipe right on a settled rowHover ↶s or ⌘⇧SBanner button, or send a message
Auto-settle when idleLong press → checkbox⋯ or right-click → checkboxnone, it is a settingSecond row of the auto-settled banner

BThe swipe tray: a short swipe offers, a full swipe commits

Swipe left already works this way: a short swipe opens the snooze presets, a full one uses your default. B gives swipe right the same shape. A short swipe holds a tray with Settle and Unread; carry on past halfway and it settles, exactly as today. Inside a session, marking unread keeps you where you are and holds the flag until you leave.

Inside a sessionStays open. The flag holds until you open another session or send a message. A toast says so.
The rowUnread is a flag, not a tier. The row keeps its place and its time, lifts to full ink, and gets the dot.
GestureShort swipe right holds Settle and Unread. Full swipe settles. iOS Mail's leading swipe, inside our existing thresholds.
Desktop hover● joins the strip, first, mirroring the tray: ● ✓ ☾ ⚑ ⋯.
Un-settle when openThe banner. After un-settling an auto-settled session, it turns into a one-time offer to stop auto-settling it.
Keysu s in the list and transcript; ⌘⇧U ⌘⇧S from the composer. Nothing navigates.

Rows

Short swipe · 25–55%, tray held
Full swipe · past 55%, Settle takes the tray
Unread row · the tray offers Read
Settled row · the tray is Un-settle alone
Marked unread · flag, keeps its tier and time
Audit brew bundleDFdotfiles · main2d
Desktop hover · ● first, like the tray
Investigate flaky e2ePEperry · main●✓☾⚑⋯

Tray order follows iOS Mail: the action a full swipe commits sits at the outer edge and stretches to take the tray, the lighter one sits next to the row. A row that is blocked on you still refuses Settle; its tray holds Unread alone.

Phone

B1 · the listTray held, and a marked row in Idle

The held stage of swipe right used to be a slower way to settle. Now it is the one place a thumb finds Mark unread without a long press.

Audit brew bundle was marked by hand: it stays in Idle, keeps "2d", and loses the 62% recede. The Unread chip counts it.

9:41✦ ▮▮▮
B2 · long pressMark unread joins the paired verbs

The top group becomes exactly the verbs that flip in place: Settle, Snooze, Pin, Mark unread. It is the same order as the tray and the hover strip, read left to right.

Rename, fork and archive keep the second group. The checkbox stays under Settle.

B3 · from the sessionYou stay; the toast explains the hold

Nothing navigates. The toast sits above the composer and says the one thing that is not obvious: reading on will not undo it.

After the toast fades, nothing on screen says the session is held unread. That is B's gap.

9:41✦ ▮▮▮
‹Sessions1DFdotfiles·main⋯
Audit brew bundle ▾
ChatTerminalDiffFiles
Kept unread until you leaveUndo
Message dotfiles…
B4 · after un-settling an auto-settled sessionThe offer comes after the signal

Before, the banner is the main doc's: Auto-settled 1 day ago · Send a message to un-settle · Un-settle. Un-settle it and the banner turns into a one-time offer, because un-settling is the moment you have told us auto-settle was wrong.

If you un-settle by sending a message, the offer shows up while the reply streams in.

9:41✦ ▮▮▮
‹Sessions2COconduit·main⋯
Wire PTY resize ▾
ChatTerminalDiffFiles
Message conduit…

Desktop

‹Sessions1Audit brew bundle ▾·DFdotfiles·main
ChatTerminalDiffFiles
⋯
Message dotfiles…

The open row carries the brand inset and the dot: that is the hold, drawn by the list itself. Five hover icons take 143 px of a 300 px sidebar, so the titles under the pointer truncate harder than they do today.

1.  Right-click, paired verbs on top

On an unread row the verb reads Mark read, with the hollow ○.

2.  The follow-up banner, desktop
Message conduit…

Keys

  • List or transcript focused: u and s flip.
  • Composer focused: ⌘⇧U and ⌘⇧S. Neither navigates.
  • The hover tooltip on ● teaches u, as ✓ teaches ⌘⇧S today.

Good

  • One rule for both swipes: short offers, full commits. The held stage of swipe right finally earns its place.
  • iOS Mail users already look for Unread on the leading swipe.
  • Staying matches what the server does anyway, and the row tells the truth: a flag, not a fresh Done.

Risky

  • Two 74 px targets under a moving thumb. A miss marks unread instead of settling; harmless, and Undo is right there.
  • Five hover icons squeeze titles in a 300 px sidebar, for the least frequent of the five verbs.
  • The hold is invisible on a phone once the toast fades.
  • The follow-up banner can land while output streams.

Cost

  • A second button on the swipe's existing held state.
  • A client-side hold, so a reconnect does not write read_at.
  • Mark read RPC; an unread_marked_at column so the row can stay in its tier.
  • One more hover icon; the follow-up banner state.
Two to three days.
ActionTouchPointerKeyAlso
Mark unreadShort swipe right → Unread, or long pressHover ●, ⋯ or right-clicku or ⌘⇧USession ⋯. You stay; it holds until you leave
Mark readShort swipe right → Read, or long pressHover ○, ⋯ or right-clicku or ⌘⇧UOpening the session; Undo
Un-settleSwipe right on a settled rowHover ↶s or ⌘⇧SBanner button, or send a message
Auto-settle when idleLong press → checkbox⋯ or right-click → checkboxnone, it is a setting"Never auto-settle it" after un-settling an auto-settled session

CThe bar owns state: a chip after the title

The session bar already says where you are. C makes it say what state the session is in: one chip after the title for Settled, Auto-settled, Snoozed, Woke and Unread. The chip is a label and a control at once; tap it for the flip verb and the auto-settle checkbox. There is no banner. The composer placeholder says what sending will do.

Inside a sessionStays open. A ● Unread chip appears in the bar and stays until you leave. Tap it to mark read.
The rowFlag, not tier, as in B.
GestureNone in the list. Long press is the touch route.
Desktop hoverUnchanged: ✓ ☾ ⚑ ⋯.
Un-settle when openThe chip's popover: Un-settle, the checkbox, and when and why it settled. Placeholder: Message to un-settle…
KeysAs B. ⌘⇧U and ⌘⇧S flip the chip you can see.

The chip, in every state it can be

Settled · by hand
Wire PTY resize ▾✓Settled
‹2Wire PTY resize✓⌄⋯
Auto-settled · by the server
Wire PTY resize ▾✓Auto-settled
‹2Wire PTY resize✓⌄⋯
Unread · held by hand
Audit brew bundle ▾Unread
‹1Audit brew bundle⌄⋯
Snoozed · the chip generalises
Wait for the nu 0.99 release ▾☾Tue 9:00
‹2Wait for the nu 0.99 release☾⌄⋯

Top of each cell: the open bar. Bottom: bar 18's collapsed row, where the chip drops to its glyph. The title's 110 px floor is what the chip spends.

Phone

C1 · settled, openedThe bar says it; the placeholder says how to leave

No banner between the transcript and the composer. The placeholder carries the implicit route, and the chip carries the explicit one.

The placeholder disappears the moment you type, which is also the moment it has done its job.

9:41✦ ▮▮▮
‹Sessions2COconduit·main⋯
Wire PTY resize ▾✓Settled
ChatTerminalDiffFiles
Message to un-settle…
C2 · auto-settled, chip tappedThe popover is the whole story

When, why, the way out, and the setting that did it, in one small menu anchored to the chip. It is the same checkbox as the session menu.

One tap deeper than a banner. Nobody sees the opt-out unless they already suspect it exists.

9:41✦ ▮▮▮
‹Sessions2COconduit·main⋯
Wire PTY resize ▾✓Auto-settled
ChatTerminalDiffFiles
Message to un-settle…
C3 · marked unread from insideThe hold is visible the whole time

Mark unread from ⋯ and the chip appears in place. It stays as long as you are here; leave and the row keeps its dot. Tap the chip to mark read.

No toast: the change is drawn where you are looking. ⌘Z still undoes it.

9:41✦ ▮▮▮
‹Sessions1DFdotfiles·main⋯
Audit brew bundle ▾Unread
ChatTerminalDiffFiles
Message dotfiles…

Desktop

‹Sessions2Wire PTY resize ▾✓Auto-settled·COconduit·main#212
ChatTerminalDiffFiles
⋯
Message to un-settle…

On desktop the chip sits right after the title, before the project and branch; the one-line bar has room. The settled shelf's hover ↶ is untouched.

Keys

  • As B: u s with the list or transcript focused, ⌘⇧U ⌘⇧S from the composer.
  • Each flip changes the chip in view, so the key has visible feedback without a toast.

Good

  • One place answers "what state is this in?" for every lifecycle state, including Snoozed and Woke, which have no in-session home today either.
  • Nothing sits between the transcript and the composer.
  • The unread hold is visible for as long as it lasts.

Risky

  • Bar 18 was hard won. The chip spends the title's width, and in the collapsed row it shrinks to a bare glyph that says little.
  • The un-settle decision happens at the composer; the chip is at the top of a tall phone.
  • "Send a message to un-settle" shrinks to a placeholder, and the auto-settle opt-out is one tap deeper than any banner.

Cost

  • Chip and popover in three bar layouts: open, collapsed, desktop.
  • Placeholder switch; client hold; Mark read RPC; unread_marked_at.
  • Revisiting §9's width budget.
About three days, most of it in the bar.
ActionTouchPointerKeyAlso
Mark unreadLong press → Mark unread⋯ or right-clicku or ⌘⇧USession ⋯; a ● Unread chip appears and holds
Mark readLong press, or tap the ● chip⋯, right-click, or the chipu or ⌘⇧UOpening the session
Un-settleSwipe right on a settled row; the chipHover ↶; the chips or ⌘⇧SSend a message, as the placeholder says
Auto-settle when idleLong press → checkbox; chip popover⋯, right-click, chip popovernone, it is a settingThe chip's popover says why it settled

DThe dot is the switch

Unread becomes one object you can point at: a dot at the row's leading edge, and the same dot before the title inside a session. Filled means there is output you have not seen; a ring means you marked it. With a pointer, clicking the dot flips it, as in Mail, Outlook and Linear. The settled banner moves down to sit on the composer, where sending happens.

Inside a sessionStays open. The ring appears before the title, in a 30 px target; tap it to mark read.
The rowA new leading gutter. Filled dot for new output, ring for marked by hand. The dot after the title goes.
GestureNone. A 7 px dot cannot be a touch target (§3: nothing under 34 px in a row), so on a phone it is a label.
Desktop hoverA faint ring appears in the gutter of a read row; click to mark unread. Click a dot to mark read.
Un-settle when openA strip fused to the top of the composer. The auto variant adds a text button.
KeysAs B.

Rows

Done, unread · filled: new output
✓Add session exportCOconduit · mainDone
Marked unread · ring: you asked
Audit brew bundleDFdotfiles · main2d
Desktop hover, read row · a ghost ring
Investigate flaky e2ePEperry · main✓☾⚑⋯
Desktop hover, unread row · click reads it
✓Add session exportCOconduit · main✓☾⚑⋯
Settled · no dot, no ring, ever
COWire PTY resize#212Auto · 1d

Phone

D1 · the listThe gutter reads down the left edge

Every unread row lines up on one vertical, so you can count them without reading. The gutter costs every row 9 px of title.

Needs-you rows are loud already; they get no dot, as today.

D2 · long pressThe sheet's icon is the ring it makes

Mark unread's icon is the hollow ring, because that is what it will put on the row. Mark read, on an unread row, shows the filled dot it removes.

Touch still has no one-step route. The dot's promise is a pointer promise.

D3 · marked unread from insideThe ring sits before the title

The only place the dot is big enough to tap on a phone: the title band has the room for a 30 px target. Tap it and it clears.

A ring before a title is easy to miss and easy to mistake for a status glyph.

9:41✦ ▮▮▮
‹Sessions1DFdotfiles·main⋯
Audit brew bundle ▾
ChatTerminalDiffFiles
Message dotfiles…
D4 · auto-settled, openedThe strip sits on the composer

A strip fused to the composer's top edge instead of a floating card: 20 px shorter, and physically attached to the thing that un-settles. The auto variant adds one text button.

Two actions, one of them a link, in 320 px. Tight, and a thumb can hit the wrong one.

9:41✦ ▮▮▮
‹Sessions2COconduit·main⋯
Wire PTY resize ▾
ChatTerminalDiffFiles
✓Auto-settled 1 day ago. Sending un-settles it.Don't auto-settle thisUn-settle
Message conduit…

Desktop

‹Sessions2Wire PTY resize ▾·COconduit·main#212 merged
ChatTerminalDiffFiles
⋯
✓Auto-settled 1 day ago. Sending un-settles it.Don't auto-settle thisUn-settle ⌘⇧S
Message conduit…

The ghost ring and its tooltip appear only while the pointer is in the row. The dot lives inside the row's <a>, so it has to be an overlaid button that stops the click, the same trick the hover strip already needs.

1.  Right-click, paired verbs on top
2.  The target, at true size
✓Add session exportCOconduit · main✓☾⚑⋯

The dot draws at 7 px and hit-tests at 19 px, measured from the row's edge. Miss by a few pixels to the right and you open the session instead. Fitts is kind to screen edges and unkind to gutters inside a sidebar.

Keys

  • As B. The keys are the same in every direction; only what they draw differs.

Good

  • The fastest pointer path of the four: one click, no menu, no hover strip.
  • Honest about why a row is unread, new output or your own flag, at a glance.
  • One object across the row, the sheet icon and the session title.

Risky

  • Half a design on the phone: the dot cannot be a touch control there, and phone is where conduit lives.
  • A new gutter changes §3's row anatomy and costs every row 9 px of title.
  • Two dot shapes is a legend people have to learn, for a distinction they rarely need.
  • A small target next to a large one that navigates.

Cost

  • Row anatomy change, the gutter button with hit slop, the ring state.
  • Title dot in both bar layouts; the composer strip.
  • Client hold; Mark read RPC; unread_marked_at.
Three to four days, plus reopening §3.
ActionTouchPointerKeyAlso
Mark unreadLong press → Mark unreadClick the ghost ring; ⋯ or right-clicku or ⌘⇧USession ⋯; the ring appears before the title
Mark readLong press; tap the title ring in a sessionClick the dot; ⋯ or right-clicku or ⌘⇧UOpening the session
Un-settleSwipe right on a settled rowHover ↶s or ⌘⇧SThe composer strip, or send a message
Auto-settle when idleLong press → checkbox⋯ or right-click → checkboxnone, it is a setting"Don't auto-settle this" in the strip

≡The four, side by side

Each row is one of the questions the brief asked. The last column is the pick, which is not always one direction's answer.

QuestionA · Menus and keysB · Swipe trayC · The barD · The dotPick
Mark unread inside a sessionMarks and leaves, both platformsStays; toast explains the holdStays; chip shows the holdStays; ring before the titleGo to the list: phone navigates, desktop is already there
"Opening marks read"Never bendsHeld until you open another session or sendSame as BSame as BB's hold, needed only on desktop
Hand-marked rowIdentical to Done, unreadFlag: keeps tier and time, gets the dotSame as BRing in a new gutterB's flag, same dot
Unread chipCounts bothCounts bothCounts bothCounts bothCounts both, live rows only
Phone gestureNoneShort swipe right holds Settle and UnreadNoneNoneB's tray
Desktop hoverUnchanged● joins the stripUnchangedGhost ring in the gutterUnchanged
Settled row's ↶UnchangedUnchanged; tray is Un-settle aloneUnchangedUnchangedUnchanged
Un-settle when openBanner above the composerBannerChip popover and placeholderStrip on the composerA's banner
Auto-settle opt-outCheckbox row in the bannerOne-time offer after un-settlingCheckbox in the chip popoverText button in the stripA's checkbox row
Keys⌘⇧U also leavesu s, ⌘⇧U ⌘⇧SSame as BSame as BB's keys
FeedbackToast on the list you land onToast in placeThe chip; no toastThe ring; no toastToast where the row lives
Accidental triggersLowLow: a tap in a held tray, with UndoLowMedium: small target beside a big oneLow
DiscoverabilityPoorHigh on phone, fair on desktopFair; opt-out hiddenHigh on desktop, poor on phoneHigh on phone, fair on desktop
Build cost~1 day2 to 3 days~3 days3 to 4 days~2 days

★Recommendation: B's tray, A's banner, and one rule for leaving

A hybrid, because each direction is right about one thing. B is right that the held stage of swipe right is wasted and that a hand-marked row should not pretend it just finished. A is right that the banner is the place to un-settle and that the setting belongs there too. Neither C's chip nor D's dot earns its cost on a phone.

What we build

  • Unread is a flag, not a tier. A hand-marked row keeps its place and its time, lifts to full ink, and gets the same dot as Done, unread. The tier and the pill already say which kind it is, so no second dot shape. Both count in the Unread chip.
  • Mark unread puts you where the list is. On a phone that means going back to it, with the toast on arrival. On desktop the list is already on screen, so you stay, the open row gets the dot, and the flag holds until you open another session or send a message. One rule; the platforms just start in different places.
  • Short swipe right holds Settle and Unread; full swipe settles, as today. Now both swipes read the same way: a short swipe offers, a full swipe commits.
  • Desktop hover is unchanged. Right-click and u are one step each; a fifth icon would squeeze every title for the least frequent verb.
  • Menus group the paired verbs: Settle, Snooze, Pin, Mark unread, with the checkbox under Settle. Same order in the sheet, right-click, session ⋯ and tray.
  • The banner stays where the main doc put it, above the composer. When the server did the settling, a second row carries Auto-settle when idle, in the menu's own words.
  • Keys: u and s with the list or transcript focused; ⌘⇧U and ⌘⇧S from anywhere, including the composer.

Why not the others, whole

  • A whole: a two-day-old session wearing a fresh Done pill misreports what happened, and closing the desktop pane punishes reading on.
  • B whole: the hover icon is the wrong trade, and the one-time offer after un-settling fires while output streams, when nobody is looking at a banner.
  • C: the right idea for a later "state everywhere" pass, but it spends bar 18's width and moves un-settle away from the composer, where the decision is made.
  • D: a pointer-first idea in a phone-first product. Worth revisiting as a desktop-only accelerator once the flag exists.

What it costs

  • MarkSessionRead RPC, for Undo and Mark read by hand.
  • unread_marked_at: set by session.unread, cleared by session.read, so tier derivation can tell a flag from fresh output.
  • A client-side hold: skip the read write when re-attaching to the session you marked, until you open a different one.
  • A second button in the swipe tray; menu and sheet reorder; the banner's second row; two chords.
About two days, and each piece ships alone.

Drawn

R1 · the listTray held; a flagged row in Idle

B's tray on the settle side. The flagged row stands out against the receded Idle rows without moving.

9:41✦ ▮▮▮
R2 · back from a sessionMarked from inside, landed on the list

⋯ → Mark unread in the session pops back to the list. The row is where it was, now flagged; the toast names it.

Undo marks it read and leaves you on the list. It does not reopen the session.

9:41✦ ▮▮▮
Sessions 18⇅⋯
All projects ▾⌕Search
Needs you 1Running 1Unread 2Settled
Marked unread Audit brew bundleUndo
R3 · long press a settled rowThe sheet flips, and drops what does not apply

Settle becomes Un-settle. Snooze and Mark unread go, because neither shelf shows them. The checkbox stays, so you can turn auto-settle off for a session without reviving it.

R4 · auto-settled, openedA's banner, unchanged from A4

The main doc's banner, plus the checkbox row when the server did it. Un-settle and sending both pause auto-settle until new activity; the checkbox makes it permanent.

9:41✦ ▮▮▮
‹Sessions2COconduit·main⋯
Wire PTY resize ▾
ChatTerminalDiffFiles
Message conduit…
‹Sessions1Audit brew bundle ▾·DFdotfiles·main
ChatTerminalDiffFiles
⋯
Message dotfiles…

Desktop, after ⌘⇧U in the open session: you are still reading it, the open row carries the brand inset and the dot, and the toast sits at the foot of the sidebar, where the row changed. The hover strip on the row above is untouched.

ActionTouchPointerKeyAlso
Mark unreadShort swipe right → Unread, or long press⋯ or right-clicku or ⌘⇧USession ⋯: phone returns to the list, desktop stays and holds
Mark readShort swipe right → Read, or long press⋯ or right-clicku or ⌘⇧UOpening the session; Undo on the toast
Un-settleSwipe right on a settled row, or long pressHover ↶, ⋯ or right-clicks or ⌘⇧SBanner button, or send a message. Pauses auto-settle until new activity
Auto-settle when idleLong press → checkbox⋯ or right-click → checkboxnone, it is a settingSecond row of the auto-settled banner

Open questions for you

  • ⌘⇧U needs checking in Safari, Chrome and Firefox on macOS before we commit to it.
  • Should settling clear unread? This page says no, as Gmail's archive doesn't, so un-settling an unread session brings it back bold. The auto-settle guard makes this rare either way.
  • Should the desktop hold survive a reload? Proposed: in memory only, so a reload counts as opening. Putting it in the URL is possible but leaks into shared links.
  • Mark unread on a row that needs you: allowed here, since it is harmless and means "remind me after I answer". Say if you would rather grey it out, like Settle.

ΔWhat would change in mobile-first-sidebar.html

For the recommendation only. Nothing here changes the structure of that doc; it adds states and corrects rows.

§1 The system

  • Frame 3, swipe right: redraw the held state as the tray, Settle at the edge and Unread beside the row. Caption: "Short swipe offers, full swipe commits." Add that a settled row's tray is Un-settle alone.
  • Frame 4, long press: the top group becomes Settle, Snooze, Pin, Mark unread (⌘⇧U), with Auto-settle when idle under Settle. The note gains: "Mark unread is hidden on settled and snoozed rows."
  • Frame 6, undo: add Mark unread to the list of toasts, and say where they go: the screen on a phone, the sidebar's foot on desktop.
  • Frame 11, settled opened: add the auto-settled variant with the checkbox row.

§3 The row

  • New state cells: Marked unread (flag, keeps tier and time), Mid-swipe, tray, Settled, mid-swipe un-settle, Settled, Auto · 1d.
  • Touch rules card: "25% reveals and holds the tray" replaces "reveals and holds".
  • Slot ② text: the dot means unread, whether new output or your own flag.

§4 Every interaction

  • Rewrite Mark unread (touch: tray or long press; key: u or ⌘⇧U; also: from a session). Add Mark read and Auto-settle when idle rows as in the table above.
  • Un-settle's Also column gains "pauses auto-settle until new activity".
  • Undo's Also column gains Mark unread.
  • Single keys card: u reads "unread / read".

§5 Desktop

  • Panel 3, right-click: the paired-verb group and the checkbox, same order as the sheet.
  • Panel 4's note says e settles; §4 says s settles and e archives. Fix the note to s.
  • The desktop frame's settled banner can show the auto variant.

§9 and §10

  • Bar 18's ⋯ sheet: the Session group gains Mark unread, and the checkbox under Settle.
  • Noticed while here: bar 18 gave Snooze ⌘⇧Z, which is Redo inside the composer. Removed 2026-09-27; Snooze has no chord.
  • §10 Backend: add unread_marked_at and a MarkSessionRead RPC. Frontend: the desktop hold. Order of work: Mark unread and the tray land with step 3; the banner's checkbox with step 5.