Skip to content

FE-743: Petri parallel execution with resource pools and per-slice sandboxes#149

Merged
kostandinang merged 6 commits into
mainfrom
ka/fe-743-petri-parallel-execution
Jun 2, 2026
Merged

FE-743: Petri parallel execution with resource pools and per-slice sandboxes#149
kostandinang merged 6 commits into
mainfrom
ka/fe-743-petri-parallel-execution

Conversation

@kostandinang
Copy link
Copy Markdown
Contributor

@kostandinang kostandinang commented May 22, 2026

Summary

  • Adds FiringPolicy (serial | parallel) to the Petri interpreter: parallel mode claims all ready transitions and fires them concurrently with Promise.allSettled, subject to pool limits.
  • Introduces shared agent resource places so test-writer and code-writer transitions contend under a configurable global concurrency cap.
  • Isolates each slice in its own sandbox directory under the run tree, which parallel execution and later epic merge depend on.

Context

  • FE-738 separated mechanical and semantic completion lanes; this PR delivers the main structural advantage of Petri over proc: independent slices can advance concurrently when policy and pools allow.
  • Planning decision gate: parallel policy must demonstrate measurable benefit on a multi-slice fixture relative to serial before the frontier is considered complete.
  • Renaming worktreeDir to sandboxDir clarifies that the path is a per-run filesystem root, not necessarily a git worktree (brownfield worktrees land in FE-755).

What changed

  • FiringPolicy: serial preserves prior single-fire behavior; parallel batches independent ready transitions.
  • RunPolicy.agentPoolSize: caps simultaneous agent-backed transitions via pool:test-agent and pool:code-agent places.
  • Per-slice sandboxes: artifacts live under join(sandboxDir, sliceId) so concurrent slices do not stomp the same tree.
  • CLI: removes dead --engine flag; adds --policy=serial|parallel for explicit policy selection at cook time.

Verification

  • Engine contract scenarios exercised under both policies (41 contract tests in this area).
  • Dedicated tests for pool bounds, concurrent firing behavior, and sandbox isolation between slices.
  • npm run verify green.

Out of scope

  • Merging slice sandboxes for epic-level verify-epic (FE-745).
  • Codebase/brownfield cook on real repos (FE-755).

Traceability

  • Requirements 46–50; SPEC §3, §4; frontier petri-parallel-execution in memory/PLAN.md; umbrella H-6476.

@cursor
Copy link
Copy Markdown

cursor Bot commented May 22, 2026

PR Summary

Medium Risk
Changes core orchestrator concurrency, token pooling, and filesystem isolation; parallel batch rollback can abort a whole step if one transition fails, and epic verification still uses the parent sandbox until merge work lands.

Overview
FE-743 delivers parallel Petri execution so independent slices can advance concurrently, with shared agent pools and per-slice sandboxes, and marks the frontier done in memory/PLAN.md.

The interpreter gains a parallel firing policy: it greedily claims tokens for all enabled transitions, runs them with Promise.allSettled, commits successes, and rolls back the whole batch on any handler rejection (including falsy rejections). serial behavior is unchanged. RunPolicy.agentPoolSize seeds capped tokens on pool:test-agent / pool:code-agent instead of per-slice agent places, bounding concurrent agent-backed work.

The net compiler and wiring pass route slice actions and tests through sandboxDir/<sliceId> (with path validation), create those dirs at wire time, and keep verify-epic on the parent sandbox (epic merge called out as follow-up). The run root is renamed sandboxDir / createSandbox across cook, types, and Pi actions.

brunch cook accepts --policy=serial|parallel; help drops the unused --engine flag. Contract and adapter tests now cover both policies, plus concurrency, pool limits, wall-clock vs serial, and sandbox isolation.

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

@kostandinang kostandinang changed the title plan: petri-parallel-execution in-progress, FE-743 assigned FE-743: Petri parallel execution — concurrent firing, resource pools, worktree-per-slice May 22, 2026
Comment thread src/orchestrator/src/petri-net.ts Outdated
Comment thread src/orchestrator/src/petri-net.ts Outdated
@augmentcode
Copy link
Copy Markdown

augmentcode Bot commented May 22, 2026

🤖 Augment PR Summary

Summary: This PR completes FE-743 by adding true parallel Petri-net execution, shared agent resource pools, and per-slice worktree isolation to reduce wall-clock time on multi-slice plans.

Changes:

  • Extend FiringPolicy to serial | parallel and implement runParallel() using greedy token claiming + Promise.allSettled.
  • Add shared pool:test-agent/pool:code-agent places and RunPolicy.agentPoolSize to cap global agent concurrency.
  • Route action contexts and test runs through join(worktreeDir, sliceId) to isolate slice execution directories.
  • Update brunch cook CLI: retire --engine, add --policy=serial|parallel, default to serial.
  • Expand contract tests to cover both policies and add explicit concurrency/pool/worktree isolation checks.
  • Update memory/PLAN.md to mark petri-parallel-execution done and adjust sequencing.

Technical Notes: Parallel execution aims for serial parity while allowing bounded concurrency via shared pool tokens.

🤖 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/net-compiler.ts Outdated
Comment thread src/orchestrator/src/engine-contract.test.ts Outdated
@kostandinang kostandinang force-pushed the ka/fe-743-petri-parallel-execution branch from 6ff7563 to d4e9d95 Compare May 22, 2026 13:32
Comment thread src/orchestrator/src/net-compiler.ts
@kostandinang kostandinang force-pushed the ka/fe-743-petri-parallel-execution branch from d4e9d95 to d43222e Compare May 22, 2026 13:57
@kostandinang kostandinang force-pushed the ka/fe-738-petri-semantic-lanes branch from 8e56a7c to f959557 Compare May 22, 2026 14:14
@kostandinang kostandinang force-pushed the ka/fe-743-petri-parallel-execution branch from d43222e to 55945f9 Compare May 22, 2026 14:14
Comment thread src/orchestrator/src/net-compiler.ts
@kostandinang kostandinang force-pushed the ka/fe-743-petri-parallel-execution branch 3 times, most recently from 13953ca to 386c3cf Compare May 22, 2026 14:31
Comment thread src/orchestrator/src/net-compiler.ts
@kostandinang kostandinang force-pushed the ka/fe-743-petri-parallel-execution branch from 386c3cf to 0f5cdbf Compare May 22, 2026 14:59
@kostandinang kostandinang force-pushed the ka/fe-738-petri-semantic-lanes branch from f959557 to 1747538 Compare May 22, 2026 14:59
Comment thread src/orchestrator/src/net-compiler.ts
Comment thread src/orchestrator/src/petri-net.ts
@kostandinang kostandinang force-pushed the ka/fe-738-petri-semantic-lanes branch from da2bb0d to 6c4fd65 Compare May 25, 2026 11:02
@kostandinang kostandinang force-pushed the ka/fe-743-petri-parallel-execution branch 2 times, most recently from 2f0aba4 to f1ff792 Compare May 25, 2026 11:05
@kostandinang kostandinang force-pushed the ka/fe-738-petri-semantic-lanes branch from 6c4fd65 to c51fdb7 Compare May 25, 2026 11:05
@kostandinang kostandinang force-pushed the ka/fe-743-petri-parallel-execution branch from f1ff792 to 33a84c1 Compare May 25, 2026 11:17
@kostandinang kostandinang force-pushed the ka/fe-738-petri-semantic-lanes branch from c51fdb7 to e76b68a Compare May 25, 2026 11:17
Comment thread src/orchestrator/src/petri-net.ts
@kostandinang kostandinang force-pushed the ka/fe-743-petri-parallel-execution branch from 421f18b to 9878f8c Compare May 28, 2026 10:34
@kostandinang kostandinang changed the base branch from ka/fe-738-petri-semantic-lanes to graphite-base/149 May 28, 2026 12:58
@kostandinang kostandinang force-pushed the ka/fe-743-petri-parallel-execution branch from 9878f8c to 1de40c9 Compare May 28, 2026 12:59
@kostandinang kostandinang changed the base branch from graphite-base/149 to ka/fe-738-petri-semantic-lanes May 28, 2026 12:59
@kostandinang kostandinang force-pushed the ka/fe-743-petri-parallel-execution branch from 1de40c9 to 8e41132 Compare May 29, 2026 12:27
Copy link
Copy Markdown
Contributor

@lunelson lunelson left a comment

Choose a reason for hiding this comment

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

Parallel firing + shared pools land cleanly, and the decision gate (parallel beats serial on wall clock) is the right thing to clear before adding this much machinery. The runSerial/runParallel split with shared restoreClaim/depositClaim helpers is nice.

Three architectural reflections, all comment-only — none block:

  1. Parallel failure semantics is all-or-nothing batch. runParallel uses Promise.allSettled, but on any rejection it restores claims for every transition in the batch and rethrows. That means one slice's transient agent failure aborts every other concurrent slice's in-flight work, not just halts the failing one. The tests don't exercise mixed success/failure batches, so this is currently invisible. Likely too coarse once real agent flakiness shows up — worth naming as an explicit design choice (or queuing per-claim rollback as follow-up).

  2. wireHandlers now has a filesystem side effect. FE-738 was careful to keep compileTopology pure and put runtime concerns in wireHandlers. This PR adds mkdirSync(sliceSandboxDir(...)) inside wireHandlers — the wiring pass now also provisions directories on disk. Small but real layering creep. Could factor out a prepareRunFilesystem(blueprint, input) step that engine.ts invokes before wireHandlers.

  3. Naming drift between abstraction and artifact. worktreeDirsandboxDir is done thoroughly across types, CLI flags, and handlers (createWorktreecreateSandbox). But the file worktree.ts still has that name, and the returned sandboxDir is still literally .cook/runs/<id>/worktree on disk. The abstraction says "sandbox," the artifact still says "worktree." OK to defer if FE-755 will revisit the on-disk convention; worth a one-line decision either way.

Pool-token contention and per-slice sandbox isolation look solid. 👍

lunelson
lunelson previously approved these changes Jun 1, 2026
Copy link
Copy Markdown
Contributor

@lunelson lunelson left a comment

Choose a reason for hiding this comment

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

Approving — architectural reflections above are non-blocking. 👍

Base automatically changed from ka/fe-738-petri-semantic-lanes to main June 1, 2026 16:33
@kostandinang kostandinang dismissed lunelson’s stale review June 1, 2026 16:33

The base branch was changed.

kostandinang and others added 4 commits June 2, 2026 09:30
Parallel firing policy (petri-net.ts):
- FiringPolicy = 'serial' | 'parallel'
- runParallel: greedy token claiming + Promise.allSettled concurrent fire
- Extracted isEnabled() private helper

Shared resource pools (net-compiler.ts):
- pool:test-agent / pool:code-agent replace per-slice agent places
- agentPoolSize on RunPolicy bounds global concurrency
- Worktree-per-slice: join(worktreeDir, sliceId) for all action contexts

CLI (cook-cli.ts):
- Retired dead --engine=proc|petri flag
- Added --policy=serial|parallel wired to createOrchestrator

Tests (engine-contract.test.ts):
- Parallel added to all engines arrays (serial parity)
- Concurrency proof, wall-clock benchmark, pool-bounded tests
- Extracted withConcurrencyTracking() helper
- Worktree isolation adapter test

Decision gate passed: parallel measurably beats serial on wall clock.

Co-authored-by: Amp <amp@ampcode.com>
Deposit fulfilled transition outputs even when a sibling sets ctx.halted in the same batch, matching serial commit semantics while still rolling back on handler rejection.

Co-authored-by: Cursor <cursoragent@cursor.com>
Per-slice test-agent/code-agent places were replaced by shared pool:*
places in FE-743; pool places are already excluded by the pool: prefix check.
@kostandinang kostandinang force-pushed the ka/fe-743-petri-parallel-execution branch from 8e41132 to a865631 Compare June 2, 2026 07:31
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 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 a865631. Configure here.

Comment thread src/orchestrator/src/petri-net.ts
@kostandinang kostandinang requested a review from lunelson June 2, 2026 07:57
kostandinang and others added 2 commits June 2, 2026 10:09
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
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.

2 participants