🤖 feat: Codex-style workspace creation card in the transcript - #4211
Conversation
git only prints checkout progress after 2s, so the creation card's progress bar never appeared for typical repos (a 12k-file checkout finished in ~2s during UAT). Force immediate progress for the worktree checkout only.
|
Preview deployment for your docs. Learn more about Mintlify Previews.
💡 Tip: Enable Automations to automatically generate PRs for you. |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
Security findingsAdvisory findings (2)
ℹ️ 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 |
🛡️ Codex Security Review · Automatically triggeredSecurity review completed. No security issues were found in this pull request. Reviewed commit: Only the user who started this review can view the report in Codex. ℹ️ About Codex security reviews in GitHubThis is an experimental Codex feature. Security reviews are triggered when:
Once complete, Codex will leave suggestions, or a comment if no findings are found. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4348f56b1b
ℹ️ 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".
- Flush the aggregator's throttled init cache right before the coalesced idle bump so a lone init-progress or init-output event is never rendered from the stale cached row. - Let checkout failures flow through the outer worktree rollback path so a failed cleanup is reported instead of swallowed. - Drop the progress bar width transition (no unrequested animation).
|
@codex review |
🛡️ Codex Security Review · Automatically triggeredSecurity review completed. No security issues were found in this pull request. Reviewed commit: Only the user who started this review can view the report in Codex. ℹ️ About Codex security reviews in GitHubThis is an experimental Codex feature. Security reviews are triggered when:
Once complete, Codex will leave suggestions, or a comment if no findings are found. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 02ec2c2e86
ℹ️ 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".
- Point HEAD at an unborn ref before the progress checkout so trusted post-checkout hooks still receive the null old commit and new-worktree flag exactly as with a plain git worktree add. - Pass --no-recurse-submodules: linked-worktree submodule repos do not exist yet, and submodule.recurse=true made the checkout fail where worktree add succeeded. syncLocalGitSubmodules materializes them.
|
@codex review |
🛡️ Codex Security Review · Automatically triggeredSecurity review completed. No security issues were found in this pull request. Reviewed commit: Only the user who started this review can view the report in Codex. ℹ️ About Codex security reviews in GitHubThis is an experimental Codex feature. Security reviews are triggered when:
Once complete, Codex will leave suggestions, or a comment if no findings are found. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 226742001f
ℹ️ 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".
- Forward git's informational stderr (Preparing worktree, Updating files, Switched to branch) as plain output so a successful card never paints routine progress in the error color; creation failures are logged as stderr from the outer catch (skipping caller cancellation). - Scroll the raw log to its end whenever it mounts or grows, so a failed card that opens its details lands on the lines explaining the failure.
|
@codex review |
|
Codex Review: Didn't find any major issues. What shall we delve into next? 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". |
🛡️ Codex Security Review · Automatically triggeredSecurity review completed. No security issues were found in this pull request. Reviewed commit: Only the user who started this review can view the report in Codex. ℹ️ About Codex security reviews in GitHubThis is an experimental Codex feature. Security reviews are triggered when:
Once complete, Codex will leave suggestions, or a comment if no findings are found. |
The transcript truncation UI test assumed the first hidden-history marker directly followed user-0; the workspace creation card now renders there. Assert the seam position (after user-0's turn, before user-1) instead of adjacency.
|
@codex review |
🛡️ Codex Security Review · Automatically triggeredSecurity review completed. No security issues were found in this pull request. Reviewed commit: Only the user who started this review can view the report in Codex. ℹ️ About Codex security reviews in GitHubThis is an experimental Codex feature. Security reviews are triggered when:
Once complete, Codex will leave suggestions, or a comment if no findings are found. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 8704b61794
ℹ️ 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".
Local worktree creation used to populate the checkout inside create(), so every checkout progress event fired before the workspace was announced and the creation card could never show the bar. WorktreeManager.createWorkspace now takes deferMaterialization: it reserves the worktree (add --no-checkout, unborn HEAD, branch mapping) and returns, and the streamed checkout, .xumignore sync, fast-forward and submodule sync move to materializeWorkspace(), which WorkspaceService.create runs after announcing the workspace. Plugin-override sanitization for deferred worktrees runs after materialization and before the init hook, like task worktrees; a sanitize failure still tears the creation down. Fork, restore, tasks, multi-project and devcontainer creation stay eager, as does task(kind="workspace"), whose agentId validation reads the checkout under the task mutex. The new IPC test subscribes after create() resolves and asserts an init-progress event arrives, which fails on the previous head.
Git's stderr for the streamed checkout mixes progress with diagnostics. The parser used to forward diagnostics as output immediately, and a failure then re-logged the whole retained buffer (bare separators included) as error output. Hold diagnostics until the exit status is known: log them as output on success, and on failure throw them as the error so the caller reports them once, line by line.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 92baaf9bd9
ℹ️ 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".
There was a problem hiding this comment.
🛡️ Codex Security Review · Automatically triggered
Here are some automated security review suggestions for this pull request.
Reviewed commit: 92baaf9bd9
ℹ️ About Codex security reviews in GitHub
This is an experimental Codex feature. Security reviews are triggered when:
- You comment "@codex security review"
- A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review
Once complete, Codex will leave suggestions, or a comment if no findings are found.
…lization exit Repointing HEAD at the unborn placeholder during creation left the branch unclaimed until the deferred checkout ran, so a competing worktree could take it and the announced workspace would fail to check out. Move the placeholder step into materializeWorkspace, immediately before the checkout, so the reserved worktree holds the branch across the gap while post-checkout still sees a fresh worktree add. Materialization can fail after the checkout populated the tracked override file (broken submodules, .xumignore), and sends proceed after a failed init, so run the plugin-override sanitization on every materialization exit rather than only on success.
|
@codex review Head 0cda234: the unborn placeholder HEAD moves into materializeWorkspace right before the checkout so the reserved worktree keeps the branch claimed across the deferred gap, and plugin-override sanitization now runs on every materialization exit (including failures after the checkout populated files). Each thread has an inline reply with the red-green test that reproduced it. |
There was a problem hiding this comment.
🛡️ Codex Security Review · Automatically triggered
Here are some automated security review suggestions for this pull request.
Reviewed commit: 0cda234430
ℹ️ About Codex security reviews in GitHub
This is an experimental Codex feature. Security reviews are triggered when:
- You comment "@codex security review"
- A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review
Once complete, Codex will leave suggestions, or a comment if no findings are found.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0cda234430
ℹ️ 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".
The deferred checkout runs inside an announced workspace, so drop --force: anything a terminal or editor wrote there in the meantime now fails the checkout with git's own message instead of being overwritten. When the checkout fails or is aborted, point HEAD back at the workspace branch so a retained worktree never commits to the unborn placeholder. Only skip the post-materialization sanitize when the workspace is being removed; archive aborts init too but keeps the checkout registered and never reruns init.
|
@codex review Head a422dae: the deferred checkout no longer uses --force (stray files fail the checkout instead of being overwritten), HEAD returns to the workspace branch on a failed or aborted checkout, and the post-materialization sanitize now runs for archive-interrupted checkouts too. Two findings are declined with reasoning inline (cross-process pending marker, checklist failure attribution); every other thread has an inline reply with its red-green test. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a422daedc9
ℹ️ 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".
…failure, kill helpers on cancel Archive aborts init but keeps the checkout registered and never reruns it, so only removal may now interrupt the deferred checkout itself; archive waits on the init settlement and therefore parks a complete checkout. A failed checkout restores the index from HEAD along with HEAD so the retained worktree shows the stray file as a modification rather than every tracked file staged for deletion. The streamed checkout kills its process tree on cancellation so a stalled smudge filter cannot hold the settlement open.
|
@codex review Head 9d65557: a failed deferred checkout now restores the index along with HEAD, archive lets the checkout finish before parking the worktree (only removal interrupts it), and the checkout kills its process tree on cancellation. Each thread has an inline reply with the red-green test that reproduced it. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9d655574fd
ℹ️ 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".
…archive stop what follows it - materializeWorkspace populates the files while HEAD still holds the branch (hooks off), so no other worktree can claim it for as long as the checkout streams; only then does HEAD move through the unborn placeholder for a fast second checkout that gives trusted post-checkout hooks the plain worktree-add arguments. - The file checkout honours a separate checkoutAbortSignal; the switch, .xumignore sync, fast-forward and submodule sync honour the init signal. materializeDeferredCheckout forwards only removal to the former, so archive still parks complete files but no longer waits on the phases after them. - Tests: a gated smudge filter holds the checkout open while a rival worktree add is refused (red on the placeholder HEAD); archiving while a trusted post-checkout hook sleeps returns promptly with a complete, clean checkout (timed out before).
|
@codex review Head d28e33a: the streamed checkout now runs while HEAD still holds the branch (hooks off), then HEAD flips through the unborn placeholder for a write-free second checkout that keeps the null-oid post-checkout arguments, so the branch stays claimed for the whole checkout; materializeWorkspace takes a removal-only checkoutAbortSignal for the file checkout while the init signal (archive too) stops the hook switch, .xumignore sync, fast-forward and submodule sync. Both round-9 threads replied to and resolved with red-green tests. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d28e33a6ac
ℹ️ 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".
… switch, failed card after an app exit - syncXumignoreFiles takes the init abort signal: the git ls-files call is cancellable and each copy checks the signal, so archive no longer waits on large ignored-file syncs. - If another worktree claims the branch in the instant between the placeholder flip and the hook switch, the failure path detaches HEAD at the branch tip instead of re-attaching, so the rival stays the sole holder and the card reports git's error (spy-injected rival test). - startInit persists the running record; replayInit finalizes a running record that no live init owns as exit code -1 with an interruption line, so a workspace whose creation died with the app shows a failed card instead of looking complete. Archive deletes the record it orphans so an archived init is not reported as an app exit. - serverUpdateRestartBlockers waits for the deferred init to settle before enabling the updater (the checkout is a blocker until then).
|
@codex review Head e501fbb: .xumignore sync honours the init abort signal; a rival that claims the branch during the placeholder instant leaves this worktree detached at the tip instead of double-attached; startInit persists the running record and replayInit finalizes an orphaned running record as a failed creation (exit -1 plus an interruption line), with archive deleting the record it orphans; serverUpdateRestartBlockers waits for the deferred init to settle. All round-10 threads replied to and resolved. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e501fbb4fd
ℹ️ 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".
collectRestartBlockers also counts inits whose in-memory state is still running: endInit turns that status final only after the final init-status write has landed, so a server-update restart can no longer slip in between logComplete and the write and replay a finished creation as interrupted. Soften the interrupted-creation line, since a hook-phase interruption leaves a complete checkout. Also give the archive-during-init unit mocks the deleteInitStatus the archive path now calls (red Test / Unit on e501fbb).
|
@codex review Head 0668eb8: the archive-during-init unit mocks gain the deleteInitStatus the archive path now calls (the red Test / Unit on e501fbb), the restart blocker keeps counting an init until its final status write has landed, and the interrupted-creation message is softened. Round 11 dispositions are inline: the restart-blocker finding is fixed; the holder-check window, the cross-process lease, and the resume/quarantine are declined with reasons (recorded under Declined review findings in the description). |
🛡️ Codex Security Review · Automatically triggeredSecurity review completed. No security issues were found in this pull request. Reviewed commit: Only the user who started this review can view the report in Codex. ℹ️ About Codex security reviews in GitHubThis is an experimental Codex feature. Security reviews are triggered when:
Once complete, Codex will leave suggestions, or a comment if no findings are found. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0668eb89eb
ℹ️ 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: Didn't find any major issues. Nice work! 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". |
🛡️ Codex Security Review · Automatically triggeredSecurity review completed. No security issues were found in this pull request. Reviewed commit: Only the user who started this review can view the report in Codex. ℹ️ About Codex security reviews in GitHubThis is an experimental Codex feature. Security reviews are triggered when:
Once complete, Codex will leave suggestions, or a comment if no findings are found. |
Summary
Replaces the always-expanded init banner pinned at the top of the transcript with a Codex-style workspace creation card: it renders directly after the user message that created the workspace, shows a step checklist with a live checkout progress bar while running, collapses to a one-line Workspace created in Ns header on success, and stays expanded with the exit code and stderr on failure.
Background
The
workspace-initrow was prepended togetDisplayedMessageswithhistorySequence: -1and rendered fully expanded forever, so every new chat opened with a wall of setup output above the first message. Runtime step markers (InitLogger.logStep) and raw hook stdout were flattened into identicalinit-outputlines, and local worktree creation rangit worktree addbuffered, so no checkout progress existed to display.Implementation
userrow of the displayed transcript (index 0 when there is none). Chronology is not usable becauseinit-startfires before the first message is persisted.init-outputgains optionalstep: trueforlogSteplines (persisted and replayed; olderinit-status.jsonfiles simply render without a checklist). A new ephemeralinit-progress { label, percent }event andInitLogger.logProgress?carry checkout progress; it is never persisted or replayed.WorktreeManager.createWorkspacenow runsgit worktree add --no-checkout;materializeWorkspacethen populates the files withgit -c core.hooksPath=/dev/null checkout --quiet --progress --no-recurse-submoduleswhile HEAD still holds the branch, usingGIT_PROGRESS_DELAY=0(no--force: the checkout runs in an announced workspace, so anything written there meanwhile fails the checkout instead of being overwritten), streaming stderr through a smallGitProgressParserthat splits on\r/\nand emits deduplicated percent updates. Git's diagnostics are held until the exit status is known and classified once: plain output on success, error output on failure. Once the files are in place HEAD moves to an unborn placeholder ref and a second, write-freegit checkoutswitches back, which keeps thepost-checkouthook contract identical to a plaingit worktree add(<null> <new> 1) while the branch stays claimed for the whole streamed checkout; and--no-recurse-submodulesmirrors whatworktree adddoes internally (linked-worktree submodule repos do not exist yet;syncLocalGitSubmodulesmaterializes them). Remote runtimes are unchanged; their existinglogStepcalls become checklist items automatically.create()has announced the workspace, so progress emitted insideruntime.createWorkspacecould never reach the card (Codex caught this; the new IPC test that subscribes aftercreate()resolves fails on the previous head).WorkspaceService.createnow asks the worktree runtime fordeferMaterialization: creation reserves the worktree (add --no-checkout, unborn HEAD, branch mapping) and returns, the workspace is announced, and the streamed checkout,.xumignoresync, fast-forward and submodule sync run inRuntime.materializeWorkspace()at the start of the background init, ahead of the init hook. This matches theRuntimecontract (create is fast, init streams) and how SSH runtimes already sync ininitWorkspace. The reserved worktree keeps HEAD on the branch through the reservation gap and the streamed checkout itself (the placeholder flip happens only after the files have landed), so no other worktree can claim the branch until the workspace is complete. Plugin-override sanitization for deferred worktrees runs on every materialization exit, success or failure, and before the hook, exactly like task worktrees; a sanitize failure still tears the creation down. A checkout failure fails the init like a remote sync failure (red card, workspace stays for inspection) and puts HEAD and the index back on the workspace branch, so the retained worktree shows a stray file as a modification rather than committing to the placeholder ref or staging every file as deleted. Only removal may interrupt the file checkout itself (checkoutAbortSignal, which kills the whole git process tree, smudge filters included); archive aborts init but keeps the checkout and never reruns it, so it waits for the files to land and parks a complete, sanitized worktree, while everything after them (hook switch,.xumignoresync, fast-forward, submodules) honours its abort,.xumignoresync included (itsgit ls-filesruns with the signal and each copy checks it). If another worktree claims the branch in the instant between the placeholder flip and the hook switch, the failure path detaches HEAD at the branch tip instead of re-attaching, so the rival stays the sole holder and the card shows git's error.startInitpersists the running init record andreplayInitfinalizes a running record that no live init owns as a failed creation (exit -1 plus an interruption line), so a creation that died with the app opens as a failed card instead of a complete-looking workspace; archive deletes the record it orphans so a cancelled init is not reported as an app exit. Fork, restore, sub-agent tasks, multi-project and devcontainer creation stay eager, andtask(kind="workspace")opts out viacreate(..., { awaitMaterialization: true })because its agentId validation reads the checkout under the task mutex.InitMessage.tsxrewritten in place: header button (aria-expanded) with shimmer while running, step checklist (check / spinner / error icon), new sharedProgressBar(role="progressbar", no animation), and a More details toggle for the raw log and project path. Expand/collapse defaults derive from status (collapsed only on success; details open once finished) with user toggles winning; the only effect keeps the newest log line in view.scheduleIdleStateBump, which now runs a pre-bump prelude that flushes the aggregator's throttled cache so a bump never renders the stale row.Validation
c900320a6fagainst a real 12k-filecoder/coderworktree with success and failing.xum/initfixtures: placement after the user bubble, running checklist and streaming details, auto-collapse on success and header toggling, failure stays expanded with red stderr, reload persistence, legacy persisted data without step flags, and 375px width with no horizontal overflow all passed. Not observed there: the live percentage bar, because git suppresses progress under 2s and that checkout took about 2s. The follow-up commit setsGIT_PROGRESS_DELAY=0, guarded by a real-gitWorktreeManagertest that fails without it (red-green verified). Not covered: sub-agent child transcripts and the packaged Electron shell (renderer only).WorktreeManagertests guard each checkout invariant and were red-green verified: progress is reported for a one-file checkout (fails withoutGIT_PROGRESS_DELAY=0),post-checkoutreceives<null-oid> <new> 1(fails without the unborn HEAD, also across the deferred split), a repo withsubmodule.recurse=truestill checks out (fails without--no-recurse-submodules), routine git chatter lands in stdout with an empty stderr, a failed checkout is rolled back with its diagnostics classified once and no\rin any logged line, a deferred worktree is reserved empty and populated bymaterializeWorkspace, a competinggit worktree addfor the reserved branch is refused during the gap (red when the placeholder HEAD is set at reservation time) and while a gated smudge filter holds the checkout mid-stream (red when the placeholder HEAD is set before the checkout), a rival that claims the branch in the placeholder instant (injected through the exec spy) leaves this worktree detached at the tip with the rival as sole holder (red on d28e33a: two holders), and a reserved-but-never-materialized worktree force-deletes cleanly (what Cancel creation does).tests/ipc/workspace/init.test.tsthrough the real ORPC path: a subscriber attaching aftercreate()resolves receivesinit-progressand sees the checkout complete before the hook (red on the previous head); a repository that tracks.xum/mcp.local.jsoncwith a committedplugin:enable has it pruned after the deferred checkout and before the hook runs (red when the deferred sanitize is removed); a failing checkout ends init with exit code -1, reports the git error once, skips the hook, and keeps the workspace; a broken submodule gitlink that fails materialization after the checkout still gets its committedplugin:enable pruned (red when the sanitize only runs on success); archiving while a slow smudge filter stalls the checkout parks a complete checkout with the enable pruned and HEAD on the branch (red with the abort-signal guard); archiving once the files have landed while a trusted post-checkout hook sleeps returns promptly with a complete, clean checkout (times out when archive is not forwarded past the file checkout);serverUpdateRestartBlockerswaits for the deferred init to settle before enabling the updater, since the checkout is a restart blocker until then.xumignore.test.ts: a cancelled signal rejects and copies nothing (copied on the previous head).initStateManager.test.ts: a running init record with no live init replays as start, error line, end(-1) and is finalized on disk (nothing was persisted beforeendIniton the previous head). WorktreeManager: cancelling a deferred checkout stalled in a smudge filter shim settles and leaves no helper processes behind (times out without killTreeOnTermination). WorktreeManager: a file written into the reserved worktree before the checkout survives and fails the checkout by name, with HEAD and index restored (red with--force).collectRestartBlockerskeeps counting an init until its final status write has landed (endInitturns the in-memory status final only after the write); theserviceContainerblocker inventory fails without it (red-green verified), and aninitStateManagertest holds the workspace file lock to check the window itself.make static-check, targeted Bun suites (aggregator, messageUtils, initStateManager, WorktreeManager, gitProgress, WorkspaceStore including a bump-timing test that fails without the pre-bump flush), Jesttests/ipc/workspace/init.test.tsandtests/ui/chat/initMessage.test.ts, and the InitMessage / App.chatLoading Storybook plays including the pinned phone viewport.Declined review findings
--force(removed to protect files the user wrote there), and the workspace may already carry the user's first prompt, so it is neither deleted nor gated at startup. The interrupted creation is reported as a failed card ("Check the checkout before using it, or recreate the workspace") and recreate is the recovery; before this PR the same crash left an orphaned directory with no workspace at all..xumignorecopy: the sync now checks the archive signal between files and itsgit ls-filessubprocess is killable; a single in-flightfs.copyFileis bounded by that one file and completes rather than leaving a torn destination. Chunked or stream-based abortable copying would add machinery to a best-effort phase for an archive that already waits on the file checkout by design (rounds 8 and 9); no further narrowing of the archive-abort contract is planned in this PR.Review record
Codex code + security review on every pushed head; each round's findings were reproduced first, fixed or declined with an inline reply, and resolved.
4348f5602ec2c202ec2c222674202267420c68f1ddc68f1dd8704b6192baaf9(deferred materialization)92baaf90cda2340cda234a422dae, 2 declined (below)a422dae9d655579d65557d28e33ad28e33ae501fbb, 1 fixed in consequence and instant declined (below)e501fbb0668eb8(restart blocker), 3 declined (below)0668eb80668eb8(re-review)The
Codex Commentsgate rejected the review summary board once it listed resolved security advisories; #4223 fixed the gate on main.Risks
create()must wait for init like it already does for SSH/Coder workspaces (tools, sends, attachments and skills already gate onwaitForInit);task(kind="workspace")keeps the eager path. A crash between announcement and materialization is reported on the next load as an interrupted creation (failed card) that the user recreates like any failed workspace. Covered by real-git tests for new-branch, existing-branch, deferred, and rollback paths; the resulting worktree, branch, and clean status are asserted.Generated with
xum• Model:anthropic:claude-fable-5-1• Thinking:xhigh• Cost:$127.35