FE-879: Lazy per-slice cook worktrees and shared node_modules for brownfield#223
FE-879: Lazy per-slice cook worktrees and shared node_modules for brownfield#223kostandinang wants to merge 2 commits into
Conversation
|
Warning This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
This stack of pull requests is managed by Graphite. Learn more about stacking. |
PR SummaryMedium Risk Overview Slice seeding symlinks
Reviewed by Cursor Bugbot for commit e35fa92. Bugbot is set up for automated code reviews on this repo. Configure here. |
Brownfield cook provisioned every slice's git worktree eagerly in wireHandlers — N `git worktree add` + N recursive node_modules CoW copies paid synchronously at startup before any slice fired. - Move slice-worktree creation into resolveSliceCwd via idempotent ensureSliceWorktree, so a slice's worktree is materialized on first fire. A run touching 2 of 8 slices pays for 2 worktrees, not 8. Synchronous provisioning serializes concurrent fires on the JS thread, so parallel-policy worktree adds never overlap. - Symlink each slice's node_modules to the parent worktree's single copy instead of CoW-copying per slice (SHAREABLE_TOP_LEVEL_ENTRIES). walkFiles already skips symlinks, so the shared tree is never re-walked during dep seeding, merge, or promotion. Other gitignored dirs still copy per slice. Correctness-neutral: same worktrees/branches, just lazy; deps resolve through the symlink. npm run verify green; adds symlink + idempotency unit tests. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Add the cook-worktree-laziness frontier definition (FE-879, done) and mark the per-slice over-copy / eager-seeding optimization resolved — closing cook-codebase-mode acceptance (8) and the sandcastle over-copy trigger. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
90bb5ef to
95ac829
Compare
3c0fa64 to
e35fa92
Compare
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit e35fa92. Configure here.
| ): string { | ||
| const sliceDir = resolveSliceWorktreeDir(parentSandboxDir, sliceId); | ||
| if (existsSync(sliceDir)) return sliceDir; | ||
| return seedSliceFromParentWorktree(parentSandboxDir, sliceId, plan, runId); |
There was a problem hiding this comment.
Slice id collision silently ignored
High Severity
ensureSliceWorktree returns immediately when the slice path already exists, without checking that it is a provisioned git worktree. If a slice id matches a top-level tracked entry in the parent sandbox (e.g. slice src when the repo has src/), cook uses that project directory as the sandbox instead of failing, breaking per-slice isolation.
Reviewed by Cursor Bugbot for commit e35fa92. Configure here.



Stack Context
Stacks on FE-864. Refines the brownfield per-slice worktree provisioning FE-755 introduced -- makes it lazy and shares node_modules -- without changing what cook produces. (
brunch serve/ FE-878 is what surfaced the startup cost.)What?
wireHandlersloop intoresolveSliceCwd, via a new idempotentensureSliceWorktree. A slice's worktree is materialized on first fire, so a run touching 2 of 8 slices pays for 2 worktrees, not 8. Rework re-fires are no-ops; provisioning is synchronous (execFileSync), so concurrent fires of distinct slices serialize on the JS thread -- no twogit worktree addcalls overlap under the parallel policy.node_modules/to the parent worktree's single copy instead of CoW-copying it per slice (SHAREABLE_TOP_LEVEL_ENTRIES).walkFilesalready skips symlinks, so the shared tree is never re-walked during dependency seeding, merge, or promotion. Other gitignored dirs (dist/) still copy per slice.Why?
In codebase mode the slice layout is always per-slice, and every slice's worktree was provisioned up front -- N
git worktree add+ N recursive node_modules CoW copies, paid synchronously before any slice fired (9 of each for an 8-slice plan). The per-slice node_modules copy dominates wall-clock.Behavior / risk
Correctness-neutral: same worktrees on the same branches, just lazy; deps resolve through the symlink. Trade-off: build caches under node_modules (
.cache,.vite) become shared across parallel slices -- fine for cook's transient runs; documented at the call site.Tests
npm run verifygreen. New unit tests: slicenode_modulesis a symlink (not a copy), other gitignored content still copies,ensureSliceWorktreeidempotent. Brownfield integration smoke unchanged.