FE-826: Orchestrator resolves greenfield/brownfield from the spec-derived plan, not plan location#181
Conversation
PR SummaryMedium Risk Overview Cook resolver split: CLI: Reviewed by Cursor Bugbot for commit 9f29209. Bugbot is set up for automated code reviews on this repo. Configure here. |
614109d to
1dfa79b
Compare
…, not plan location Greenfield vs brownfield is now plan truth carried from the spec, not an inference from where plan.yaml sits on disk. - `Plan` gains a `mode: 'greenfield' | 'brownfield'`; `brunch plan <specId>` threads `specification.mode` through the snapshot → projection → reconciliation → emitted plan.yaml. `loadPlan` defaults a missing/legacy mode to greenfield. - `resolveCookMode` splits into `resolveCookPlan` (locates the plan path only) and `resolveSandboxPlan` (chooses the worktree strategy from `plan.mode`): greenfield → empty worktree, generate from scratch, no git gate; brownfield → clone the cwd repo, requiring a clean git working tree. - A spec-emitted greenfield plan now uses an empty worktree instead of always cloning the cwd; brownfield-smoke gains a "never clones" greenfield oracle. Reverses SPEC §D50 (mode = plan location) and refines I123-K — reconciled separately via ln-sync. Plan fixtures regenerated with explicit mode. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
`brunch cook` with no positional directory now runs against the launch cwd (BRUNCH_LAUNCH_CWD || process.cwd()) and looks for `.brunch/` there, instead of erroring on a missing argument. Help text reads `cook [dir]`. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
- Requirement 46: `brunch cook [dir]` (dir optional, defaults to cwd). - Requirement 50: mode-driven resolver — locate the plan, then read the plan's spec-derived `mode` to choose the worktree strategy; mode is carried in plan.yaml from `specification.mode`, not inferred from plan location. - Add decision D162-K (greenfield/brownfield is spec-derived plan truth); refine invariant I123-K (clone is brownfield-only; greenfield uses an empty worktree even from a spec plan). - Lexicon: fixture/codebase mode rows are now mode-selected, not location-keyed. - PLAN: add FE-826 cook-mode-from-spec frontier (branch-complete). - Retire memory/CARDS.md (both cards landed). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1dfa79b to
9f29209
Compare
lunelson
left a comment
There was a problem hiding this comment.
This makes the cook mode source much clearer: plan truth now carries through from the spec instead of depending on where the file happens to live.
One small question: in src/orchestrator/src/plan-loader.ts, plans with a missing mode default to greenfield, which seems right for legacy/authored plans. But an explicit unknown value also falls back to greenfield. Do we want typoed modes to fail loudly instead?

Summary
Greenfield/brownfield is now spec-derived plan truth, not an inference from where
plan.yamlsits on disk. Mode is a property of the specification, so it travels with the plan and drives the worktree strategy.What Changed
Plangainsmode: 'greenfield' | 'brownfield';brunch plan <specId>threadsspecification.modethrough snapshot → projection → reconciliation → emittedplan.yaml.loadPlandefaults a missing/legacy mode to greenfield.resolveCookMode→resolveCookPlan(locate the plan path) +resolveSandboxPlan(mode-driven worktree: greenfield → empty worktree; brownfield → clone the cwd repo, clean-tree gate). A spec-emitted greenfield plan no longer clones the cwd.brunch cook [dir]defaults to the launch cwd.Reverses the location-keyed reading of SPEC Requirement 50; adds D164-K, refines I123-K (clone is brownfield-only). Engine/topology plan fixtures regenerated with an explicit
mode.Verification
npm run verifygreen (1706 tests, build).brownfield-smokegains a "greenfield-from-spec never clones" oracle alongside the brownfield clone path.🤖 Generated with Claude Code