Repository navigation
feat(preview): identify and stop retained thread processes - #280
Conversation
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d808a37024
ℹ️ About Codex in GitHub
Your team has set up Codex to 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 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
UI evidence for The baseline and updated menu screenshots show the conditional stop command and new dividers. The confirmation and pending screenshots show shutdown feedback. The fast recording captures a normal stop. The slow recording delays only the selected thread’s stop request by four seconds: loading feedback remains for 5.1 seconds until completion, then confirms shutdown. The selected thread’s process indicator disappears; the unrelated thread still has its running process. Astra High round 2 reviewed the whole PR at this head/base and found no actionable defects. Native mobile presentation was not tested on a device. fast-stop.mp4slow-stop.mp4 |
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c5afeb68ad
ℹ️ About Codex in GitHub
Your team has set up Codex to 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 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
c5afeb6 to
123e6cb
Compare
|
@codex review |
123e6cb to
41eeae1
Compare
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 41eeae1deb
ℹ️ About Codex in GitHub
Your team has set up Codex to 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 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: fb5b7d0b8b
ℹ️ About Codex in GitHub
Your team has set up Codex to 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 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
fb5b7d0 to
f0188c0
Compare
|
@codex review |
Show each managed preview expiry next to its terminal process. Offer a thread-only stop command when a preview or subprocess remains, with grouped menus across clients and cancellation that interrupts recovery. Carry-Group: incubator Carry-Observation: Preview lifecycle metadata and cancellation share one service and typed client contract, so the core change must travel together.
Offer the shared thread preview and process stop command in the legacy sidebar, with dividers after new-thread, annotation, and persistence controls. Carry-Group: legacy-sidebar Carry-Observation: Optional legacy sidebar integration reuses the core preview control service.
Carry-Group: incubator Preview lease subscriptions now wait for the selected session and recheck its capability after reconnecting. Focused tests cover startup, reconnect, unsupported servers, and session-tagged fallback values. Implemented with GPT-6.1-Sol in the Codex harness.
Carry-Group: incubator Show immediate shutdown feedback in web, desktop, and native mobile, retaining it through completion and for at least three seconds. The stop service now awaits the selected thread’s existing terminal cleanup fibers and reports failed termination. Validation: focused backend and mobile timing tests, scoped typechecks and lint, and Browser checks for three-second and delayed shutdown feedback. Implemented with GPT-6.1-Sol in the Codex harness.
Keep failed terminal handles visible and retry their termination on a later stop. Hold the thread lock while selecting, closing, and awaiting cleanup so concurrent opens and restarts cannot escape that shutdown interval. Validation: 135 focused backend tests, scoped server typecheck, lint, and formatting passed. Implemented with GPT-6.1-Sol in the Codex harness. Carry-Group: incubator
Register lifecycle labels, branding, and a summary action for preview_stop_thread so every published MCP tool has a presentation definition. Validation: 14 registry and tool presentation tests, shared typecheck, scoped lint and formatting passed. Implemented with GPT-6.1-Sol in the Codex harness. Carry-Group: incubator
Dismiss the global shutdown feedback when the environment interrupts the stop request, instead of showing a failure that cannot be confirmed. Retire interrupted feedback so a late completion cannot revive it, and preserve feedback from a newer request. Validation: six focused feedback tests, mobile typecheck, scoped lint, formatting, and diff checks passed. Implemented with GPT-6.1-Sol in the Codex harness. Carry-Group: incubator
Wait for actual PTY exit callbacks before reporting that retained processes stopped. Bound confirmation after force-kill, keep unconfirmed processes visible and retryable, and remove their metadata if an exit arrives later. Add regression cases for cached and delayed exit, timeout and retry, thread locking and isolation, and exit subscription cleanup. Clarify the PTY adapter's termination contract and make test PTYs emit actual exit events. Formatting and diff checks passed. Tests and typechecks run in GitHub CI only at the maintainer's request. Implemented with GPT-6.1-Sol in the Codex harness. Carry-Group: incubator
Track each shutdown independently so finishing or interrupting one request cannot clear another pending stop. Show aggregate progress and completed outcomes, retaining each result for its own minimum visibility. Add deterministic concurrency regression cases. Source formatting and diff checks completed; validation runs in GitHub CI only at the maintainer request. Implemented with GPT-6.1-Sol in the Codex harness. Carry-Group: incubator
Reject automatic attachment while the same terminal still has an unconfirmed retained exit witness and no live session process. Keep retained processes visible and retryable, and allow normal attachment after confirmed exit or to an intentional live replacement. Add deterministic regressions for termination grace, repeated attachment after failed shutdown, processless replacements and thread isolation. Source formatting and diff checks completed; tests run in GitHub CI only at the maintainer request. Implemented with GPT-6.1-Sol in the Codex harness. Carry-Group: incubator
Capture attachment lifecycle before waiting for the thread lock. Keep a temporary count of shutdown operations through lock finalization so metadata removal or an interrupted concurrent stop cannot let an automatic attachment recreate a terminal. Add deterministic coverage for queued attachment, delayed metadata removal, concurrent idle close and interrupted shutdown. Fresh attachment remains possible after shutdown completes. Source formatting and diff checks passed; test execution is delegated to GitHub CI at the maintainer request. Implemented with GPT-6.1-Sol in the Codex harness. Carry-Group: incubator
Hold the closed-event consumer awaited by shutdown itself instead of an independently published metadata-removal event. This proves the attachment is queued while Stop owns the lock after metadata disappears, regardless of exit-observer scheduling. Source formatting and diff checks completed. Test execution runs in GitHub CI only at the maintainer request. Implemented with GPT-6.1-Sol in the Codex harness. Carry-Group: incubator
|
Codex Review: Didn't find any major issues. 🚀 Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
f0188c0 to
b7b28ff
Compare
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b7b28ff801
ℹ️ About Codex in GitHub
Your team has set up Codex to 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 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Stopping a slow process held the environment-wide preview reservation gate until its terminal exited, delaying unrelated launches. Order reservations and cleanup by thread, while retaining the short shared gate for atomic port ownership and keeping readiness cancellable. Added deterministic regressions for blocked shutdown, same-thread ordering, concurrent port reservations, and immediate launch/recovery cancellation. Source formatting and diff checks passed; tests run in GitHub CI only at the maintainer request. Implemented with GPT-6.1-Sol in the Codex harness. Carry-Group: incubator
|
@codex review |
|
Codex Review: Didn't find any major issues. Hooray! Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
A merge that landed while a checkpoint was validating discarded the run: repaired checkpoints published tag and main in one atomic push, so the validated tag was rejected and the repair had to be reselected and revalidated by hand; ordinary checkpoints published their tag but failed the run at promotion. Publish the validated tag and source ref without touching main, and have promotion defer, instead of failing, when main advanced or a guarded merge holds the main write lock. The merge's own service request then publishes a revision that replays it onto the new tag and promotes that. Merges after recovery selection no longer invalidate it; only a main that no longer descends from the selected source does. Carry-Group: tooling Carry-Observation: On 2026-10-05 the merges of #280 and #282 each forced a manual fold-in and full revalidation of a repaired checkpoint. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
A merge that landed while a checkpoint was validating discarded the run: repaired checkpoints published tag and main in one atomic push, so the validated tag was rejected and the repair had to be reselected and revalidated by hand; ordinary checkpoints published their tag but failed the run at promotion. Publish the validated tag and source ref without touching main, and have promotion defer, instead of failing, when main advanced or a guarded merge holds the main write lock. The merge's own service request then publishes a revision that replays it onto the new tag and promotes that. Merges after recovery selection no longer invalidate it; only a main that no longer descends from the selected source does. Carry-Group: tooling Carry-Observation: On 2026-10-05 the merges of #280 and #282 each forced a manual fold-in and full revalidation of a repaired checkpoint. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
A merge that landed while a checkpoint was validating discarded the run: repaired checkpoints published tag and main in one atomic push, so the validated tag was rejected and the repair had to be reselected and revalidated by hand; ordinary checkpoints published their tag but failed the run at promotion. Publish the validated tag and source ref without touching main, and have promotion defer, instead of failing, when main advanced or a guarded merge holds the main write lock. The merge's own service request then publishes a revision that replays it onto the new tag and promotes that. Merges after recovery selection no longer invalidate it; only a main that no longer descends from the selected source does. Carry-Group: tooling Carry-Observation: On 2026-10-05 the merges of #280 and #282 each forced a manual fold-in and full revalidation of a repaired checkpoint. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
A merge that landed while a checkpoint was validating discarded the run: repaired checkpoints published tag and main in one atomic push, so the validated tag was rejected and the repair had to be reselected and revalidated by hand; ordinary checkpoints published their tag but failed the run at promotion. Publish the validated tag and source ref without touching main, and have promotion defer, instead of failing, when main advanced or a guarded merge holds the main write lock. The merge's own service request then publishes a revision that replays it onto the new tag and promotes that. Merges after recovery selection no longer invalidate it; only a main that no longer descends from the selected source does. Carry-Group: tooling Carry-Observation: On 2026-10-05 the merges of #280 and #282 each forced a manual fold-in and full revalidation of a repaired checkpoint. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Merging a PR while a checkpoint was validating threw the run away. Repaired checkpoints published the tag and `lastcode/main` in one `--atomic` push, so a mid-run merge rejected the validated tag too. The repair then had to be reselected, with the merge folded in by hand, and fully revalidated. Ordinary checkpoints published their tag but failed the run at promotion, which alerted the maintenance thread. On 2026-10-05, #280 and #282 each cost a manual fold-in and a 10–15 minute revalidation. The validated tag no longer depends on main: - **Repaired checkpoints** publish the tag and immutable source ref atomically, then promote separately, the same as ordinary checkpoints. - **Promotion defers instead of failing** when main has advanced to a descendant of the candidate's source or git's lease rejects the push because a descendant merge landed mid-push. A rewrite that drops the pinned source still fails promotion after tag publication, and the rejected-push path fetches the competing head before checking ancestry. The run succeeds and logs that promotion is left to the next run. Failure to acquire the promotion lock still fails the run after the tag publishes; the lock ref cannot prove its writer is active, and abandoned locks or authentication/transport errors must remain visible to maintenance. - The guarded merge already requests a service run, and the supervisor runs it straight after the current run. That run publishes a revision replaying only the merged work onto the new tag, then promotes it. If main still equals the source, it promotes the published tag directly. - **Merges after recovery selection no longer invalidate it.** Only a main that no longer descends from the selected source (for example, rewritten by another promotion) requires reselection. - **Recovery cleanup follows promotion validation.** A main rewrite or promotion failure keeps the repaired worktree and selection for inspection. Retry promotes the existing immutable tag without republishing; successful promotion or validated descendant deferral releases the repair. You can merge at any time. The build can start from the checkpoint tag immediately, and merged work follows minutes later as a revision. Runbook text in `fork-conventions.md`, `release.md`, `nightly-workflow.md` and the `lastcode-pr` skill is rewritten to match. Validation: focused checkpoint and recovery tests, selected-recovery lifecycle tests, and carry lifecycle tests pass. Lifecycle regressions cover descendant merges after selection, during validation, and during the promotion push; unrelated remote-only rewrites retain the selected repair and fail visibly while preserving the published tag and rewritten main. They also verify blocked retries preserve that repair, restored-source retries promote the existing tag, and promotion-lock failures retain recovery until a successful retry. The scripts typecheck and scoped format/lint checks pass. GitHub CI and Codex review are required on the final head and base. Quick CI was skipped at the maintainer's request; GitHub CI is the gate. Includes merged #293 as its current base. Implemented with Claude Opus 5.5 in the Claude Code harness. Refreshed and repaired with GPT-6.1-Sol in the Codex harness. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Carry-Source-Ref: refs/lastcode/carry-sources/pr-294/e70ba03bd32f5e16161d968d3da613b6bd5b0d9b Carry-Source-Base: 00eaf51 Carry-Source-Head: e70ba03






Retained previews look like unexplained terminal processes after a thread finishes, and there is no single way to stop them. Show process identities and preview expiry in the sidebar hover, and offer “Stop all previews & processes” only when the thread has something to stop.
Group the thread menu with dividers and add shutdown feedback across web, desktop, and mobile. Feedback appears immediately and stays through terminal cleanup or three seconds, whichever takes longer; stopping a preview also cancels its retained recovery lease. Cleanup waits for an actual PTY exit event and holds the thread lock so concurrent opens or restarts cannot escape the stop. Unconfirmed termination stays visible and retryable; a later exit clears its indicator. Terminal attachment cannot start a replacement while the previous process is still terminating. Mobile tracks concurrent stops independently; interruption removes only its own feedback, and completed outcomes remain visible alongside pending shutdowns.
Validation runs in GitHub CI only at the maintainer's request. Regression coverage includes shutdown and retry, actual exit confirmation, delayed and cached exits, thread locking and isolation, late metadata removal, observer cleanup, attachment during termination, tool presentation, and concurrent mobile feedback timing and interruption. Integrated Browser checks covered preview expiry, conditional menus, thread isolation, fast three-second feedback, and delayed shutdown feedback. Desktop QA was accepted by the user. Native mobile visual QA was not run. The complete change receives independent Astra High source review and exact-head Codex review.
Before/after screenshots and shutdown timing recordings: #280 (comment).
Implemented with GPT-6.1-Sol in the Codex harness.