Skip to content

FE-1109: Reconcile executor sandbox worktrees and test runner ports#275

Open
kostandinang wants to merge 6 commits into
graphite-base/275from
ka/fe-1109-cook-sandbox
Open

FE-1109: Reconcile executor sandbox worktrees and test runner ports#275
kostandinang wants to merge 6 commits into
graphite-base/275from
ka/fe-1109-cook-sandbox

Conversation

@kostandinang

@kostandinang kostandinang commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Part of the orchestrator-alpha-cutover (FE-1089) — the first real-execution layer of the arc that re-grows the cook orchestrator natively on the alpha branch.

Two run-lifecycle steps that used to fake execution now do the real thing, behind small injected ports so the executor core stays free of git and shell calls.

What changed

  • Worktree creation (execute_worktree_create) — runs a real git worktree add instead of making an empty folder.
  • Test result (execute_test_result) — runs npm run verify in that worktree and records the real pass/fail, instead of reading a pre-written results file.

Both sit behind an ExecutionPorts seam: the core only knows the port types; the real git/shell work lives in the app layer and is injected at startup. Also folds in the port-internals cleanup from #276.

Behavior notes

  • A failing test still advances the run; only a runner that can't start blocks it.
  • A failed git worktree add leaves the run untouched.
  • No agents run, nothing is merged or landed, and execute mode isn't user-facing yet.

Verified

npm run verify green — 165 test files, 1117 passed, build OK. Tests cover both ports (command shape, pass/fail, spawn failure) and the failure paths.

Stacked on #274.

@cursor

cursor Bot commented Jul 1, 2026

Copy link
Copy Markdown

PR Summary

Medium Risk
Medium: execute-mode cook tools now spawn real git and npm subprocesses against the host repo and run worktrees; failure handling is explicit but misconfiguration or partial worktree state could affect local git state under .brunch/cook/runs/.

Overview
Delivers the executor-sandbox slice of the orchestrator cutover: cook runs get a real git workspace and real verify results instead of mkdir worktrees and prewritten test-result.json files.

ExecutionPorts seam — New types-only src/executor/execution-ports.ts (GitWorktreePort, TestRunnerPort, stubs for future agent/land). Executor core stays on fs + injected ports; app layer adds command-runner, git-worktree-port (git worktree add --detach), and test-runner-port (npm run verify). Pi composition wires defaults and allows test overrides via executionPorts.

execute_worktree_create — Calls the port instead of mkdir; reported side effects use git_worktree_add rather than mkdir. Failures return worktree_create_failed without advancing run.json; idempotent retry and recovery when a .git worktree marker already exists.

execute_test_result — Runs verify in the run worktree via TestRunnerPort, appends slice_test_result with verdict/exit code, and drops the prewritten-file path and testResultPath metadata. Failed tests still advance the run; only spawn/execution failure (test_run_failed) leaves metadata unchanged.

Docs/plan updates mark FE-1109 built, rename cook-execution-ports → execution-ports in SPEC/PLAN, extend I52-L coverage, refresh skills/TOPOLOGY, and remove completed memory/REFACTOR.md.

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

Comment thread src/executor/worktree.ts
@kostandinang kostandinang changed the title FE-1109: Real executor sandbox: git worktree + test runner ports FE-1109: Executor sandbox worktrees and test runner ports Jul 1, 2026
@kostandinang kostandinang force-pushed the ka/fe-1109-cook-sandbox branch from 8ee8fe2 to 4434358 Compare July 1, 2026 02:33
@kostandinang

Copy link
Copy Markdown
Contributor Author

Addressed the Bugbot finding: execute_worktree_create is now idempotent. Calling it a second time returns already_created instead of failing on git worktree add (which errors when the directory already exists). Added a test that the git port runs only once. npm run verify is green.

kostandinang added a commit that referenced this pull request Jul 1, 2026
The FE-1089 handoff described the descriptive scaffold as still in
progress; it is now superseded (PRs #274/#275/#276 open, executor arc
underway). Handoff files are volatile transfer state, so retire it.
@kostandinang kostandinang force-pushed the ka/fe-1109-cook-sandbox branch 2 times, most recently from 3299af6 to 873f91b Compare July 1, 2026 07:32
Comment thread src/executor/worktree.ts Outdated
Comment thread src/executor/worktree.ts

kostandinang commented Jul 1, 2026

Copy link
Copy Markdown
Contributor Author

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.
Learn more

This stack of pull requests is managed by Graphite. Learn more about stacking.

Introduce the executor execution-ports seam and the first real capability
port. execute_worktree_create now creates the run workspace through an
injected GitWorktreePort (real git worktree add --detach <dir> HEAD in the
app layer) instead of a direct mkdir, keeping executor core free of
git/subprocess (D52-L) and one-explicit-side-effect discipline (I52-L).

- src/executor/execution-ports.ts: types-only ExecutionPorts bag
  (GitWorktreePort + placeholder AgentRunnerPort/TestRunnerPort/GitLandPort)
- src/app/git-worktree-port.ts: app-layer git subprocess implementation
- src/executor/worktree.ts: inject port; add worktree_create_failed variant
  that does not advance run metadata; report git_worktree_add side effect
- pi-extensions: optional executionPorts option, inject into the adapter
- tests: app-layer port contract, injection, failure-does-not-persist,
  shared fake-ports helper for lifecycle setup helpers
- memory/PLAN.md, memory/SPEC.md: mark GitWorktreePort slice done, de-cook
  the execution-ports naming

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

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 a825f18. Configure here.

Comment thread src/executor/worktree.ts
kostandinang and others added 4 commits July 1, 2026 09:47
Second capability of the executor sandbox. execute_test_result now runs
the real verify subprocess in the run's git worktree through an injected
TestRunnerPort instead of reading a prewritten test-result.json.

- execution-ports.ts: add TestRunnerPort (run -> completed{verdict,exitCode}
  | failed{message}); testRunner is now a required ExecutionPorts member
- src/app/test-runner-port.ts: app-layer 'npm run verify' subprocess
- src/executor/test-result.ts: run injected port; report true verdict +
  exit code; add test_run_failed (runner cannot execute -> no metadata
  advance); remove prewritten testResultPath model
- run.ts: drop stale testResultPath metadata field
- pi-extensions: default + inject testRunner into the adapter
- tests: app-layer port contract, injection, failing-verdict-advances,
  runner-failure-does-not-persist; shared fake-ports helper
- TOPOLOGY.md, scope-execution-task skill, PLAN.md, SPEC.md: reflect real
  verify-subprocess ingestion; mark executor-sandbox slices done
Address Cursor Bugbot: the injected GitWorktreePort path always ran
'git worktree add', which fails when the worktree directory already
exists — unlike the prior mkdir path that could be safely retried.
A second create now returns 'already_created' without re-invoking git.
* FE-1110: Drop unused cwd from TestRunArgs

The test runner runs inside the worktree, so the repo-root cwd was dead
weight carried only for shape-symmetry with GitWorktreeCreateArgs. Remove
it from the port arg type, the executor call site, and the port tests.
Pure interface tidy; no behavior change. (REFACTOR.md commit 1/3)

* FE-1110: Extract shared app-layer command-runner

Both execution ports duplicated the same spawn-based subprocess runner.
Extract it into a single command-runner module (spawn wrapper +
CommandResult carrying an explicit spawnError signal); the git-worktree
and test-runner ports now keep only their command/args and result mapping.

Behavior preserved: the git port still surfaces its spawn-error text, now
via a spawnError fallback, locked by a new git spawn-failure test.
(REFACTOR.md commit 2/3)

* FE-1110: Consolidate port test fakes onto shared fake-ports

Three copies of the port fakes existed: the shared fake-ports helper, a
parametrized inline fake in the worktree test, and local copies in the
extension registry test. Parametrize the shared git-worktree fake with an
optional create override, then point the worktree and registry tests at
the shared helpers and delete their local duplicates. (REFACTOR.md commit 3/3)

* FE-1110: Remove completed refactor plan

REFACTOR.md was a temporary execution aid; all three commits landed.
Co-authored-by: Cursor <cursoragent@cursor.com>
@kostandinang kostandinang force-pushed the ka/fe-1109-cook-sandbox branch from a825f18 to 6c8c072 Compare July 1, 2026 07:48
Co-authored-by: Cursor <cursoragent@cursor.com>
@kostandinang kostandinang changed the title FE-1109: Executor sandbox worktrees and test runner ports FE-1109: Reconcile executor sandbox worktrees and test runner ports Jul 1, 2026
@kostandinang kostandinang changed the base branch from ka/fe-1089-orchestrator-alpha-cutover to graphite-base/275 July 1, 2026 09:46
kostandinang added a commit that referenced this pull request Jul 1, 2026
The FE-1089 handoff described the descriptive scaffold as still in
progress; it is now superseded (PRs #274/#275/#276 open, executor arc
underway). Handoff files are volatile transfer state, so retire it.
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