Skip to content

🤖 feat: Codex-style workspace creation card in the transcript - #4211

Merged
ibetitsmike merged 17 commits into
mainfrom
mike/workspace-creation-transcript
Sep 11, 2026
Merged

🤖 feat: Codex-style workspace creation card in the transcript#4211
ibetitsmike merged 17 commits into
mainfrom
mike/workspace-creation-transcript

Conversation

@ibetitsmike

@ibetitsmike ibetitsmike commented Sep 11, 2026

Copy link
Copy Markdown
Contributor

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-init row was prepended to getDisplayedMessages with historySequence: -1 and 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 identical init-output lines, and local worktree creation ran git worktree add buffered, so no checkout progress existed to display.

Implementation

  • Placement: the card is inserted after the first user row of the displayed transcript (index 0 when there is none). Chronology is not usable because init-start fires before the first message is persisted.
  • Contract: init-output gains optional step: true for logStep lines (persisted and replayed; older init-status.json files simply render without a checklist). A new ephemeral init-progress { label, percent } event and InitLogger.logProgress? carry checkout progress; it is never persisted or replayed.
  • Local checkout progress: WorktreeManager.createWorkspace now runs git worktree add --no-checkout; materializeWorkspace then populates the files with git -c core.hooksPath=/dev/null checkout --quiet --progress --no-recurse-submodules while HEAD still holds the branch, using GIT_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 small GitProgressParser that splits on \r/\n and 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-free git checkout switches back, which keeps the post-checkout hook contract identical to a plain git worktree add (<null> <new> 1) while the branch stays claimed for the whole streamed checkout; and --no-recurse-submodules mirrors what worktree add does internally (linked-worktree submodule repos do not exist yet; syncLocalGitSubmodules materializes them). Remote runtimes are unchanged; their existing logStep calls become checklist items automatically.
  • Deferred local materialization: the renderer only subscribes once create() has announced the workspace, so progress emitted inside runtime.createWorkspace could never reach the card (Codex caught this; the new IPC test that subscribes after create() resolves fails on the previous head). WorkspaceService.create now asks the worktree runtime for deferMaterialization: creation reserves the worktree (add --no-checkout, unborn HEAD, branch mapping) and returns, the workspace is announced, and the streamed checkout, .xumignore sync, fast-forward and submodule sync run in Runtime.materializeWorkspace() at the start of the background init, ahead of the init hook. This matches the Runtime contract (create is fast, init streams) and how SSH runtimes already sync in initWorkspace. 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, .xumignore sync, fast-forward, submodules) honours its abort, .xumignore sync included (its git ls-files runs 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. startInit persists the running init record and replayInit finalizes 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, and task(kind="workspace") opts out via create(..., { awaitMaterialization: true }) because its agentId validation reads the checkout under the task mutex.
  • UI: InitMessage.tsx rewritten in place: header button (aria-expanded) with shimmer while running, step checklist (check / spinner / error icon), new shared ProgressBar (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.
  • Store: init output and progress events coalesce UI bumps through scheduleIdleStateBump, which now runs a pre-bump prelude that flushes the aggregator's throttled cache so a bump never renders the stale row.

Validation

  • Remote dogfood UAT (Coder Agents) on the pre-polish head c900320a6f against a real 12k-file coder/coder worktree with success and failing .xum/init fixtures: 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 sets GIT_PROGRESS_DELAY=0, guarded by a real-git WorktreeManager test that fails without it (red-green verified). Not covered: sub-agent child transcripts and the packaged Electron shell (renderer only).
  • Real-git WorktreeManager tests guard each checkout invariant and were red-green verified: progress is reported for a one-file checkout (fails without GIT_PROGRESS_DELAY=0), post-checkout receives <null-oid> <new> 1 (fails without the unborn HEAD, also across the deferred split), a repo with submodule.recurse=true still 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 \r in any logged line, a deferred worktree is reserved empty and populated by materializeWorkspace, a competing git worktree add for 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).
  • Jest tests/ipc/workspace/init.test.ts through the real ORPC path: a subscriber attaching after create() resolves receives init-progress and sees the checkout complete before the hook (red on the previous head); a repository that tracks .xum/mcp.local.jsonc with a committed plugin: 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 committed plugin: 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); serverUpdateRestartBlockers waits 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 before endInit on 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).
  • Restart blocker: collectRestartBlockers keeps counting an init until its final status write has landed (endInit turns the in-memory status final only after the write); the serviceContainer blocker inventory fails without it (red-green verified), and an initStateManager test holds the workspace file lock to check the window itself.
  • Not yet re-run after the deferral: the remote dogfood UAT above (renderer behaviour is unchanged; the bar now has a window to appear during the checkout).
  • make static-check, targeted Bun suites (aggregator, messageUtils, initStateManager, WorktreeManager, gitProgress, WorkspaceStore including a bump-timing test that fails without the pre-bump flush), Jest tests/ipc/workspace/init.test.ts and tests/ui/chat/initMessage.test.ts, and the InitMessage / App.chatLoading Storybook plays including the pinned phone viewport.

Declined review findings

  • Cross-process pending marker for deferred registrations: needs a second Xum process to register the same half-populated worktree directory as a project-dir local workspace during the checkout; task worktrees already have this shape today, and holding the cross-process registration lock across whole checkouts would block every other registration. Left as a known tradeoff.
  • Checklist failure marker lands on the most recent step (a completion-style step such as "Fetched latest from origin" can be marked failed when the next operation fails): fixing it needs explicit per-step status in the init-output contract; the git error is shown in the red output right below. Follow-up candidate.
  • Resuming or quarantining a deferred checkout after an app exit: the working tree may hold partially written files, so a resumed populate would need --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.
  • Closing the placeholder instant between the symbolic-ref and the hook switch: two consecutive local git commands with nothing in between; removing it means dropping the null-oid post-checkout contract (round 2) or a cross-process lock (declined above). A lost race now fails loudly with a single holder instead of a silent double claim. The holder check and the restore inside that failure path are likewise two consecutive git commands (round 11); the same tradeoff applies and no further narrowing is planned.
  • Aborting an in-flight .xumignore copy: the sync now checks the archive signal between files and its git ls-files subprocess is killable; a single in-flight fs.copyFile is 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.
  • Cross-process owner or lease for init records: two Xum processes sharing one config root is not a supported configuration, so replay treats a running record with no live init in this process as an interrupted creation.

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.

Head Findings Disposition
4348f56 3 (P1, P2, P2) fixed in 02ec2c2
02ec2c2 2 (P1, P2) fixed in 2267420
2267420 2 (P2, P2) fixed in c68f1dd
c68f1dd none ("Didn't find any major issues")
8704b61 2 (P2, P2) fixed in 92baaf9 (deferred materialization)
92baaf9 3 (P2, P2, security) fixed in 0cda234
0cda234 5 (P1, P1, P1, P2, security) 3 fixed in a422dae, 2 declined (below)
a422dae 3 (P1, P1, P1) fixed in 9d65557
9d65557 2 (P1, P1) fixed in d28e33a
d28e33a 3 (P1, P2, P2) 2 fixed in e501fbb, 1 fixed in consequence and instant declined (below)
e501fbb 4 (P1, P2, P2, P2) 1 fixed in 0668eb8 (restart blocker), 3 declined (below)
0668eb8 1 (P2) declined (below)
0668eb8 (re-review) none ("Didn't find any major issues"), security review clean

The Codex Comments gate rejected the review summary board once it listed resolved security advisories; #4223 fixed the gate on main.

Risks

  • Medium, local workspace creation: the two-step checkout changes how every local worktree is materialized, and UI-created worktrees are now announced before their files exist. Anything that reads the checkout right after create() must wait for init like it already does for SSH/Coder workspaces (tools, sends, attachments and skills already gate on waitForInit); 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.
  • Low, transcript ordering: only the init row moves; other rows keep array order. Reconnect replay idempotency is unchanged and tested.

Generated with xum • Model: anthropic:claude-fable-5-1 • Thinking: xhigh • Cost: $127.35

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.
@mintlify

mintlify Bot commented Sep 11, 2026

Copy link
Copy Markdown

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated
Mux 🟢 Ready View Preview Sep 11, 2026, 11:28 AM

💡 Tip: Enable Automations to automatically generate PRs for you.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 11, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-11T20:27:31.360056Z 0668eb8 Manual request
🔒 Security Review Completed 2026-09-11T20:30:10.169483Z 0668eb8 Manual request

Security findings

Advisory findings (2)

ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@ibetitsmike

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

🛡️ Codex Security Review · Automatically triggered

Security review completed. No security issues were found in this pull request.

Reviewed commit: 4348f56b1b

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ 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.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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".

Comment thread src/browser/stores/WorkspaceStore.ts Outdated
Comment thread src/node/worktree/WorktreeManager.ts Outdated
Comment thread src/browser/components/ProgressBar/ProgressBar.tsx Outdated
- 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).
@ibetitsmike

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

🛡️ Codex Security Review · Automatically triggered

Security review completed. No security issues were found in this pull request.

Reviewed commit: 02ec2c2e86

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ 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.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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".

Comment thread src/node/worktree/WorktreeManager.ts Outdated
Comment thread src/node/worktree/WorktreeManager.ts Outdated
- 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.
@ibetitsmike

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

🛡️ Codex Security Review · Automatically triggered

Security review completed. No security issues were found in this pull request.

Reviewed commit: 226742001f

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ 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.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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".

Comment thread src/browser/features/Messages/InitMessage.tsx Outdated
Comment thread src/node/worktree/WorktreeManager.ts Outdated
- 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.
@ibetitsmike

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. What shall we delve into next?

Reviewed commit: c68f1dd1d1

ℹ️ 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".

@chatgpt-codex-connector

Copy link
Copy Markdown

🛡️ Codex Security Review · Automatically triggered

Security review completed. No security issues were found in this pull request.

Reviewed commit: c68f1dd1d1

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ 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.

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.
@ibetitsmike

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

🛡️ Codex Security Review · Automatically triggered

Security review completed. No security issues were found in this pull request.

Reviewed commit: 8704b61794

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ 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.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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".

Comment thread src/node/worktree/WorktreeManager.ts
Comment thread src/node/worktree/WorktreeManager.ts Outdated
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.
@ibetitsmike

Copy link
Copy Markdown
Contributor Author

@codex review

Head 92baaf9: local worktree materialization now runs in the background init phase (so the checkout progress is observable after the workspace is announced) and checkout diagnostics are classified once by exit status. Both earlier threads are answered inline and resolved.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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".

Comment thread src/node/worktree/WorktreeManager.ts Outdated
Comment thread src/node/worktree/WorktreeManager.ts Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛡️ 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.

Comment thread src/node/services/workspaceService.ts Outdated
…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.
@ibetitsmike

Copy link
Copy Markdown
Contributor Author

@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.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛡️ 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.

Comment thread src/node/services/workspaceService.ts Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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".

Comment thread src/node/worktree/WorktreeManager.ts Outdated
Comment thread src/node/services/workspaceService.ts
Comment thread src/browser/features/Messages/InitMessage.tsx
Comment thread src/node/services/workspaceService.ts
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.
@ibetitsmike

Copy link
Copy Markdown
Contributor Author

@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.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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".

Comment thread src/node/worktree/WorktreeManager.ts Outdated
Comment thread src/node/services/workspaceService.ts
Comment thread src/node/worktree/WorktreeManager.ts Outdated
…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.
@ibetitsmike

Copy link
Copy Markdown
Contributor Author

@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.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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".

Comment thread src/node/services/workspaceService.ts
Comment thread src/node/worktree/WorktreeManager.ts Outdated
…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).
@ibetitsmike

Copy link
Copy Markdown
Contributor Author

@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.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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".

Comment thread src/node/worktree/WorktreeManager.ts
Comment thread src/node/worktree/WorktreeManager.ts Outdated
Comment thread src/node/services/workspaceService.ts
… 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).
@ibetitsmike

Copy link
Copy Markdown
Contributor Author

@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.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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".

Comment thread src/node/worktree/WorktreeManager.ts
Comment thread src/node/services/initStateManager.ts
Comment thread src/node/services/initStateManager.ts
Comment thread src/node/services/initStateManager.ts
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).
@ibetitsmike

Copy link
Copy Markdown
Contributor Author

@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).

@chatgpt-codex-connector

Copy link
Copy Markdown

🛡️ Codex Security Review · Automatically triggered

Security review completed. No security issues were found in this pull request.

Reviewed commit: 0668eb89eb

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ 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.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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".

Comment thread src/node/worktree/xumignore.ts
@ibetitsmike

Copy link
Copy Markdown
Contributor Author

@codex review

Same head 0668eb8, no code change since the last pass: the one round-12 finding (aborting an in-flight .xumignore copy) is declined inline with reasons and recorded under Declined review findings.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Nice work!

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".

@chatgpt-codex-connector

Copy link
Copy Markdown

🛡️ Codex Security Review · Automatically triggered

Security review completed. No security issues were found in this pull request.

Reviewed commit: 0668eb89eb

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ 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.

@ibetitsmike
ibetitsmike added this pull request to the merge queue Sep 11, 2026
Merged via the queue into main with commit edafeff Sep 11, 2026
51 of 57 checks passed
@ibetitsmike
ibetitsmike deleted the mike/workspace-creation-transcript branch September 11, 2026 20:52
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