Skip to content

docs: settle teardown design (review before implementation) - #1067

Merged
arul28 merged 2 commits into
mainfrom
ade/settle-teardown-design
Aug 10, 2026
Merged

docs: settle teardown design (review before implementation)#1067
arul28 merged 2 commits into
mainfrom
ade/settle-teardown-design

Conversation

@arul28

@arul28 arul28 commented Aug 10, 2026

Copy link
Copy Markdown
Owner

Design deliverable for the settle teardown cut from #1059. Doc only — no code. Requested for review before any reimplementation is scheduled.

docs/features/terminals-and-sessions/settle-teardown-design.md

  • §1 — all seven paths that write or clear settled_at, with file:line and callers. Four of the seven clearers are implicit (never named "unsettle"), and one (setLastOutputPreview) runs per terminal output chunk. This inventory is the thing Background-work liveness in canonical phase + archive port-lease ordering #1059 didn't do first.
  • §2 — six-case race matrix. R1/R2/R6 share one root: the settle decides at t₀ and writes at t₀+T with no detector for what changed in between. lastActivityAt is not that detector — it's backed by last_output_at, which turn-start never writes.
  • §3 — proposal: a single settle-writer chokepoint owning a monotonic persisted lifecycle revision (settle writes conditionally on it), an explicit exclusive settling state, and the rule that an accepted user turn aborts the settle, never the reverse. Plus the open decision on unconfirmed teardown (§3d) — the one place the honest answer and the quiet answer differ, flagged for sign-off.
  • §4 — all 16 P1 findings mapped to the constraint each implies and the mechanism that neutralises it.
  • §5 — sequencing. The chokepoint alone, shipped with no teardown at all, would have prevented 9 of the 16 findings.

🤖 Generated with Claude Code

Greptile Summary

This documentation-only PR specifies the proposed architecture and rollout sequence for race-safe session settlement and teardown.

  • Inventories settlement and clearing entry points and models six teardown races.
  • Proposes a host-authoritative writer chokepoint, lifecycle revision, explicit settling state, and activity-driven abort behavior.
  • Defines handling for unconfirmed teardown residue and a staged implementation plan.

Confidence Score: 4/5

The PR should not merge as the approved implementation design until the outstanding mutation inventory is made internally consistent.

The design requires every settlement mutation to pass through one chokepoint, but its inventory still gives conflicting counts and classifications, so implementers cannot reliably determine the complete scope of that invariant.

Files Needing Attention: docs/features/terminals-and-sessions/settle-teardown-design.md

Important Files Changed

Filename Overview
docs/features/terminals-and-sessions/settle-teardown-design.md Adds the teardown design, race matrix, lifecycle-state proposal, compatibility constraints, and rollout sequence; the previously reported mutation-inventory ambiguity remains unresolved.

Sequence Diagram

sequenceDiagram
  participant Caller
  participant SessionService
  participant Teardown
  participant Activity
  Caller->>SessionService: Request settle
  SessionService->>SessionService: Enter settling and capture revision
  SessionService->>Teardown: Stop runtime work
  alt Accepted user activity arrives
    Activity->>SessionService: Clear lifecycle marker
    SessionService->>Teardown: Abort remaining stops
    SessionService-->>Caller: settle_aborted_by_activity
  else Revision remains unchanged
    Teardown-->>SessionService: Stop results
    SessionService->>SessionService: Conditionally persist settled_at
    SessionService-->>Caller: Typed settle outcome
  end
Loading

Reviews (2): Last reviewed commit: "docs(sessions): amend settle-teardown de..." | Re-trigger Greptile

Context used:

Deliverable for the settle teardown cut from #1059, for review before any
reimplementation.

Contains the full inventory of all seven paths that write or clear settled_at
with file:line and callers (four of the seven clearers are implicit, and one
runs per terminal output chunk), a six-case race matrix, and a proposed design:
a single settle-writer chokepoint owning a monotonic persisted lifecycle
revision, an explicit exclusive 'settling' state, and the rule that an accepted
user turn aborts the settle rather than the reverse.

Every one of the 16 P1 findings from the six review rounds is mapped to the
design constraint it implies and the mechanism that neutralises it, so the
review capital is not lost. Three findings are load-bearing: enumerate the
writers first, verify the detector actually changes on the event it guards, and
put the guarantee in the writer rather than each caller. #1059 did none of the
three.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@vercel

vercel Bot commented Aug 10, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
ade Ignored Ignored Preview Aug 10, 2026 7:24am

@coderabbitai

coderabbitai Bot commented Aug 10, 2026

Copy link
Copy Markdown

Important

Review skipped

Review was skipped due to path filters

⛔ Files ignored due to path filters (1)
  • docs/features/terminals-and-sessions/settle-teardown-design.md is excluded by !docs/**

CodeRabbit blocks several paths by default. You can override this behavior by explicitly including those paths in the path filters. For example, including **/dist/** will override the default block on the dist directory, by removing the pattern from both the lists.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 92fd099e-3011-4fd7-915b-b80e5698ee99

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Comment thread docs/features/terminals-and-sessions/settle-teardown-design.md
Five amendments from design review of #1067.

1. C4 during settling — the sharpest hole. Teardown itself produces output, so
   if C4 bumped the guard revision or tripped abort, every real teardown would
   self-abort and a settle could never land. Added a per-clearer behavior table
   for the settling window: C3/C6/C7 (turn start, turn failed, attention
   request) abort because each represents a human decision that outranks
   settled; C4/C5 (output preview, activity touch) are SWALLOWED — no clear, no
   revision bump, no abort. Before settling starts all five behave as today.

2. Multi-device authority — VERIFIED BYPASSABLE, now a hard precondition.
   terminal_sessions is a CRR table and iOS writes settled_at into its own
   replica optimistically (Database.swift:2128, from SyncService.swift:9286)
   before sending the remote command. Intent routes through the host
   chokepoint correctly, but the replica write carries no revision, so a host
   guard that REJECTS a settle can still be overridden by the phone's row
   merging upstream. Step 0 of the sequencing is now: make settled_at
   host-authoritative and replace the optimistic write with local pending UI.

3. Revision column — local-only. C4 writes terminal_sessions per output chunk
   and cr-sqlite clocks are per column, so a revision column on that table
   would add a clock entry to the highest-frequency write in the product for a
   value no other device can use. It goes in a local-only table in
   LOCAL_ONLY_CRR_EXCLUDED_TABLES, keyed by session id, with an in-memory
   fallback that degrades identically to the settling state on restart.

4. 3d signed off with both additions: the residue must stay discoverable
   (diagnostics surface + orphan-reaper eligibility, not just a label, with
   detached nohup/setsid work reported separately since it is genuinely
   unreachable), and an analytics event per docs/logging.md — coarse reason and
   bucketed count, deduplicated per session so a failing fleet is not a burst.

5. Abort result decided: typed settle_aborted_by_activity, never silent success,
   with the contract documented for all five entry points. PR-merge auto-settle
   additionally must not mark a PR handled for an aborted session.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@arul28
arul28 merged commit 2c3d41d into main Aug 10, 2026
37 checks passed
@arul28
arul28 deleted the ade/settle-teardown-design branch August 10, 2026 07:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant