Skip to content

FE-755: Cook codebase mode for brownfield brunch#155

Open
kostandinang wants to merge 5 commits into
ka/fe-747-petri-declarative-routingfrom
ka/fe-755-cook-codebase-mode
Open

FE-755: Cook codebase mode for brownfield brunch#155
kostandinang wants to merge 5 commits into
ka/fe-747-petri-declarative-routingfrom
ka/fe-755-cook-codebase-mode

Conversation

@kostandinang
Copy link
Copy Markdown
Contributor

@kostandinang kostandinang commented May 26, 2026

Summary

  • resolveCookMode selects fixture vs codebase when .brunch/cook/plan.yaml is present, the tracked working tree is clean, and the target directory is a git repository.
  • Codebase runs use a parent git worktree on branch cook/<runId> and per-slice worktrees on cook-slice/<runId>/<sliceId>, with copy-on-write for untracked/gitignored content where the OS supports it.
  • Cook run artifacts live under .brunch/cook/runs/<runId>/ (replacing .cook/); adds docs/praxis/orchestration-guide.md for operators running cook on real repos.

Context

  • Stacks on the Petri substrate delivered in FE-738 through FE-747. This frontier moves brunch cook from fixture-only greenfield runs to brownfield repositories while keeping the user’s source branch byte-identical for the duration of a run.
  • Hybrid sandboxes avoid fully duplicating large trees (node_modules, build outputs): APFS clonefile, Linux reflink, then cpSync fallback.
  • Agent invocation (pi-actions.ts) stays unchanged at the seam; only sandbox resolution and filesystem layout change.

What changed

  • Brownfield resolver wired into the existing cook CLI entry; fixture mode behavior unchanged when resolver conditions are not met.
  • cowCopy seeds untracked/gitignored files into slice sandboxes without mutating the source checkout.
  • Slice id validation rejects ids that would collide with real repo paths.
  • Integration coverage via brownfield-smoke.integration.test.ts plus a documented 2026-05-26 real-pi smoke on a temporary git repo.

Verification

  • Unit tests for mode resolver, sandbox paths, and hybrid seed behavior.
  • Brownfield integration smoke; full npm run verify green (1449 tests at PR time).

Out of scope

  • Branch commit/merge promotion and artifact lifecycle (cook-artifact-lifecycle frontier).
  • Evaluator tool scoping and Sandcastle adoption.

Traceability

  • Requirements 46–50; SPEC §D50, §A49, §I123-K; frontier cook-codebase-mode in memory/PLAN.md; stacks on FE-747.

@kostandinang kostandinang changed the title FE-755: Cook codebase-mode — brownfield resolver for brunch cook. FE-755: Cook codebase-mode — brownfield resolver for brunch cook May 26, 2026
@kostandinang kostandinang marked this pull request as ready for review May 26, 2026 17:03
@cursor
Copy link
Copy Markdown

cursor Bot commented May 26, 2026

PR Summary

Medium Risk
New git worktree and filesystem sandbox logic must preserve the source-repo byte-identical invariant; mistakes could touch the user's checkout, though resolver gates and integration tests target that boundary.

Overview
Cook brownfield mode replaces the reserved "not implemented" path: resolveCookMode picks fixture (plan.yaml) vs codebase (.brunch/cook/plan.yaml), requiring a git repo and a clean tracked working tree (untracked .brunch/ is ignored). Run output moves from .cook/ to .brunch/cook/runs/<runId>/.

Codebase runs seed sandboxes with git worktree add on cook/<runId>, per-slice worktrees on cook-slice/<runId>/<sliceId>, and CoW copies of untracked/gitignored top-level dirs (node_modules, etc.) so agents see real deps without duplicating the whole tree. The petrinet path calls seedSliceFromParentWorktree when sandboxMode is codebase; pi-actions is unchanged.

Petri declarative routing (FE-747 prep): branching handlers use typed RouteGuard + evalRouteGuard instead of inline routeField checks; enumerateCandidateOutputs exposes topology-only output places for static analysis. Docs/SPEC/PLAN and a new docs/praxis/orchestration-guide.md describe operator workflow; brownfield-smoke.integration.test.ts locks source-byte-identical isolation.

Reviewed by Cursor Bugbot for commit e549e84. Bugbot is set up for automated code reviews on this repo. Configure here.

Copy link
Copy Markdown
Contributor Author

Comment thread src/orchestrator/src/epic-sandbox-merge.ts
@augmentcode
Copy link
Copy Markdown

augmentcode Bot commented May 26, 2026

🤖 Augment PR Summary

Summary: This PR implements “codebase mode” for brunch cook <dir>, enabling brownfield runs against an existing git repo while keeping the source branch’s tracked files unchanged.

Changes:

  • Introduced resolveCookMode(dir) (fixture/codebase/error) and replaced the prior “not yet implemented” exit.
  • Added a clean-tree gate for codebase mode using git status --porcelain --untracked-files=no and rejected non-git dirs.
  • Extended createSandbox to support codebase mode via git worktree add -b cook/<runId> ... HEAD.
  • Added per-slice seeding from the parent worktree (excluding .git, sibling slice dirs, and __epic__/) and wired it into the Petri net compiler.
  • Threaded sandboxMode through orchestrator input so engines can branch on fixture vs codebase behavior.
  • Consolidated cook run output paths from .cook/ to .brunch/cook/ and updated docs/spec/plan accordingly.
  • Added unit + integration coverage, including an end-to-end brownfield smoke test using a real tmp git repo.

Technical notes: Codebase mode checks out a separate worktree branch (cook/<runId>) and runs agents against seeded slice worktrees without mutating the source repo’s HEAD or tracked-file status.

🤖 Was this summary useful? React with 👍 or 👎

Copy link
Copy Markdown

@augmentcode augmentcode Bot left a comment

Choose a reason for hiding this comment

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

Review completed. 2 suggestions posted.

Fix All in Augment

Comment augment review to trigger a new review at any time.

Comment thread src/orchestrator/src/epic-sandbox-merge.ts
Comment thread src/orchestrator/src/net-compiler.ts Outdated
Comment thread src/orchestrator/src/net-compiler.ts
@kostandinang kostandinang force-pushed the ka/fe-755-cook-codebase-mode branch from 4e77df6 to c2cfb6e Compare May 27, 2026 20:44
@kostandinang kostandinang force-pushed the ka/fe-747-petri-declarative-routing branch from ee16289 to eef2f05 Compare May 27, 2026 20:44
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit c2cfb6e. Configure here.

Comment thread src/orchestrator/src/worktree.ts
Comment thread src/orchestrator/src/epic-sandbox-merge.ts Outdated
@kostandinang kostandinang changed the title FE-755: Cook codebase-mode — brownfield resolver for brunch cook FE-755: Cook codebase mode for brownfield brunch cook May 27, 2026
kostandinang and others added 5 commits May 27, 2026 23:12
`brunch cook <dir>` now runs against an existing repo. When
`<dir>/.brunch/cook/plan.yaml` exists and the working tree's tracked
files are clean, cook initializes the sandbox via
`git worktree add <sandboxDir> -b cook/<runId> HEAD` from the source
repo, per-slice worktrees are seeded by file-copy from the parent
(excluding `.git`, sibling slice dirs, and `__epic__/`), and pi-actions
run unchanged against pre-existing code. The source branch in `<dir>`
stays byte-identical.

Also consolidates cook's filesystem footprint from `<cwd>/.cook/` to
`<cwd>/.brunch/cook/` so all cook state lives under the existing
`.brunch/` workspace convention.

Acceptance criteria covered:
- Resolver replaces the "not yet implemented" early-exit at
  cook-cli.ts:65-70 with a pure `resolveCookMode(dir)` discriminated
  union (fixture / codebase / error).
- Clean-tree gate refuses brownfield runs with uncommitted tracked
  changes (`git status --porcelain --untracked-files=no`).
- `createSandbox` gains a `CreateSandboxOptions` discriminated union;
  codebase mode invokes `git worktree add` on branch `cook/<runId>`.
- `seedSliceFromParentWorktree` populates per-slice dirs from the
  parent worktree contents.
- `OrchestratorInput.sandboxMode?: 'fixture' | 'codebase'` threads the
  mode through to net-compiler.
- `pi-actions.ts` unchanged. Existing greenfield fixture-mode tests
  pass; new tests in cook-cli.test.ts (resolveCookMode), worktree.test.ts
  (codebase-mode createSandbox), epic-sandbox-merge.test.ts
  (seedSliceFromParentWorktree), plus a tmpdir+fake-actions
  brownfield-smoke.integration.test.ts that pins source-byte-identical
  isolation. Total: 1447/1447 tests pass.

Known follow-ons (out of scope for this PR):
- pi-actions evaluator currently gets full write tools, collapsing the
  TDD-shaped workflow when pi can satisfy the slice during evaluation.
- No "promote cook artifact back" story — modification lives in
  untracked subdirs of the cook branch's worktree, not as commits.
- Multi-slice brownfield over-copy (TODO in `seedSliceFromParentWorktree`)
  — slice 2's 1-slice fixture didn't exercise it.

A 2026-05-26 spike evaluated `@ai-hero/sandcastle` for hybrid adoption.
Technically viable (built-in pi provider, decoupled worktree primitives,
noSandbox available) but deferred until sandcastle ships 1.0 or
multi-slice over-copy becomes a measurable bottleneck.

A 2026-05-26 outer-loop smoke against a tmpdir git repo with real pi
confirmed in-place file modification and source-byte-identical isolation
end-to-end.

Updates SPEC §D50, §A49, §I123-K, §Lexicon (path consolidation) and
PLAN.md `cook-codebase-mode` frontier definition (now Recently
Completed with three follow-on findings).

Co-Authored-By: Claude <noreply@anthropic.com>
Slice 3 of FE-755 refactors per-slice worktree population into a hybrid
mechanism. Tracked content arrives via `git worktree add` on a slice-level
branch (`cook-slice/<runId>/<sliceId>`); untracked/gitignored content
(`node_modules/`, `dist/`, etc.) arrives via copy-on-write (`cp -c` on
macOS APFS, `cp --reflink=auto` on Linux btrfs/xfs/zfs, recursive `cpSync`
fallback).

Solves the multi-slice over-copy problem flagged as a TODO in slice 2
(~90% disk savings on CoW filesystems) while keeping runtime deps present
so pi-actions can run `npm test`/`bun test` against the slice worktree.

Slice branches use the `cook-slice/<runId>/<sliceId>` sibling namespace
rather than nesting under `cook/<runId>/<sliceId>` because git refs are
leaf-or-directory: with `cook/<runId>` already a leaf, the nested form
fails with "cannot lock ref ... 'refs/heads/cook/<runId>' exists."

OrchestratorInput.runId threads through from cook-cli for slice-branch
naming. pi-actions.ts unchanged.

Test changes:
- epic-sandbox-merge.test.ts: rewrites seedSliceFromParentWorktree tests
  around real git parents — tracked-via-git, untracked-via-CoW, slice-level
  branch checkout, sibling-slice exclusion, __epic__ exclusion.
- brownfield-smoke.integration.test.ts: passes runId; asserts the slice
  worktree is on its cook-slice/<runId>/<sliceId> branch.
- Verify: 123 test files, 1449 tests pass; 0 errors.

Also: docs/praxis/cook-brownfield.md — brunch-specific operational guide
covering pre-flight, hand-authored vs ln-scope-derived plans, the
absolute-path invocation gotcha, source-byte-identical verification,
manual artifact promotion, and cleanup.

PLAN.md updated: the multi-slice over-copy follow-on is retired (subsumed
by this work). `cook-artifact-lifecycle` remains as a separate proposed
frontier: commit slice work, replace mergeSlicesIntoEpicSandbox's file-copy
with `git merge` of slice branches (surfaces real conflicts; today's
behavior is silent last-slice-wins), and merge epic branches back to
cook/<runId> so `git merge cook/<runId>` becomes the promotion path. This
slice sets up the substrate (real slice branches) so that frontier can
land cleanly on top.

Co-Authored-By: Claude <noreply@anthropic.com>
…tion.

Renames docs/praxis/cook-brownfield.md → docs/praxis/orchestration-guide.md
to make room for the doc to grow beyond pure brownfield-mode notes (e.g.
greenfield fixture workflows, future graph-compiled plans).

Restructures the "Author the plan" section to lead with the intended
long-term target: read the plan from a spec-graph projection emitted by
`petri-graph-compilation` (currently blocked on FE-700 intent-graph-
semantics). Until that lands, two interim bridges remain — `/ln-scope`-
then-translate (most disciplined) and one-shot pi translation (cheap) —
plus hand-authoring as an escape hatch for one-off experiments.

Co-Authored-By: Claude <noreply@anthropic.com>
Fail before git worktree add when a slice id matches an existing
top-level path in the parent worktree (e.g. src/).

Co-authored-by: Cursor <cursoragent@cursor.com>
git worktree add only checks out tracked files; CoW-copy missing
top-level entries from the source cwd when creating the parent sandbox
so slice seeding inherits node_modules/dist-style artifacts. Extract
cowCopy into cow-copy.ts with complete JSDoc and reuse for slice seed.

Co-authored-by: Cursor <cursoragent@cursor.com>
@kostandinang kostandinang force-pushed the ka/fe-755-cook-codebase-mode branch from c2cfb6e to e549e84 Compare May 27, 2026 21:13
@kostandinang kostandinang force-pushed the ka/fe-747-petri-declarative-routing branch from eef2f05 to 578e7c9 Compare May 27, 2026 21:16
@kostandinang kostandinang changed the title FE-755: Cook codebase mode for brownfield brunch cook FE-755: Cook codebase mode for brownfield brunch May 27, 2026
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