Skip to content

feat(runtime): implement P2 bounded deterministic parallel proposal scheduling - #1109

Merged
enricopiovesan merged 1 commit into
mainfrom
claude/issue-1092-p2-parallel-scheduling
Aug 23, 2026
Merged

feat(runtime): implement P2 bounded deterministic parallel proposal scheduling#1109
enricopiovesan merged 1 commit into
mainfrom
claude/issue-1092-p2-parallel-scheduling

Conversation

@enricopiovesan

Copy link
Copy Markdown
Collaborator

Summary

Implements #1092 per spec 110-bounded-parallel-workflow-scheduling FR-001
through FR-005: bounded deterministic parallel scheduling and execution for
P1 runtime workflow proposals. Independent branches in an already-approved
proposal DAG can now run concurrently, subject to fan-out/join-width/
queue-depth/concurrency bounds and a pure_read-only concurrency
restriction (FR-004a) for this first implementation.

  • traverse-contracts::proposal: ParallelScheduleLimits and
    compute_parallel_schedule — levelizes an already-canonicalized,
    acyclic proposal into concurrency waves (BFS-by-level, lexicographic
    tie-break within a wave, mirroring P1's Kahn's-algorithm tie-break) and
    rejects any exceeded fan-out/join-width/queue-depth bound before doing
    any work (FR-005). No wire-format change — P2 schedules the exact same
    WorkflowProposal shape P1 validates.
  • traverse-runtime::parallel_proposal: enforce_pure_read_only_parallelism
    (FR-004a — a wave with more than one member is denied unless every
    member is pure_read); execute_parallel_proposal, dispatching each
    wave on real OS threads (std::thread::scope, bounded to
    max_concurrent_nodes per batch) and folding outcomes back in
    lexicographic order regardless of actual completion order, so the trace
    stays deterministic (FR-002) despite real concurrency. Wall-time and
    per-wave payload-byte budgets are checked between waves — Rust has no
    safe way to preempt an in-flight OS thread, and FR-004a already limits
    concurrent work to side-effect-free reads, so an already-dispatched wave
    always finishes; a panicking executor is surfaced as a Failed outcome
    rather than silently dropped.
  • traverse-mcp::tools::parallel_proposals: compute_schedule_for_proposal
    and execute_parallel_proposal_via_mcp, mirroring tools::proposals'
    plain-function pattern. Factored authorize_and_reserve_quota out of
    P1's execute_proposal_via_mcp (behavior-preserving refactor, all 22
    existing P1 tests pass unchanged) so P1 and P2 share one FR-006/
    FR-006a/FR-007b implementation instead of duplicating it.
  • docs/bounded-parallel-proposal-scheduling.md documents the wave
    model, every bound, the pure_read-only rule, the determinism and
    cancellation semantics, and the MCP surface.

Closes #1092

Governing Spec

  • 110-bounded-parallel-workflow-scheduling
  • 109-runtime-workflow-proposals
  • 070-runtime-event-sink-boundary

Project Item

Project 1 item for #1092: PVTI_lADOEbiBt84Bbyp1zg3fR6U (In Progress).

Validation

  • cargo test --workspace — all suites pass, including 8 new scheduling
    tests (traverse-contracts), 12 new authorization/execution/
    concurrency-bound tests (traverse-runtime), and 16 new end-to-end MCP
    tests (traverse-mcp), plus all 22 pre-existing P1 MCP tests unchanged
    after the shared-helper refactor.
  • cargo clippy --workspace --all-targets — clean.
  • cargo fmt --check — clean.
  • bash scripts/ci/coverage_gate.sh — passes: traverse-contracts and
    traverse-runtime at 100.00%, traverse-mcp at 99.08% (> 98%
    threshold).
  • bash scripts/ci/spec_alignment_check.sh — clean against this PR body.

Non-goals

Matches spec 110's own "Out of scope": dynamic fan-out expansion, cycles,
durable waits, retry/saga semantics, and implicit parallelism inferred by
a planner. Per ADR-0042, P3 (durable orchestration) and P4 (promotion)
remain separately spec-gated and are not unlocked by this PR.

…cheduling

Extends the P1 sequential proposal lifecycle with wave-based concurrent
execution of independent branches, restricted to pure_read capabilities
in this first implementation per FR-004a. Reuses the P1 wire format,
canonicalization, and cross-validation unchanged; P2 only adds a
levelization/scheduling pass and a concurrent executor on top.

- traverse-contracts::proposal: ParallelScheduleLimits (fan-out, join
  width, queue depth, concurrency bounds) and compute_parallel_schedule,
  levelizing an already-canonicalized proposal into concurrency waves via
  Kahn's-algorithm-style BFS, rejecting any exceeded bound before doing
  any work.
- traverse-runtime::parallel_proposal: enforce_pure_read_only_parallelism
  (FR-004a); execute_parallel_proposal, dispatching each wave on real OS
  threads bounded to max_concurrent_nodes, folding outcomes back in
  lexicographic (not completion) order for a deterministic trace;
  wall-time and per-wave payload-byte budgets checked between waves
  (Rust has no safe way to preempt an in-flight thread); a panicking
  executor surfaces as a Failed outcome rather than being dropped.
- traverse-mcp::tools::parallel_proposals: compute_schedule_for_proposal
  and execute_parallel_proposal_via_mcp, mirroring tools::proposals and
  reusing its authorize_and_reserve_quota helper (factored out of P1's
  execute_proposal_via_mcp, which now uses it too) so P1 and P2 share one
  FR-006/FR-006a/FR-007b implementation.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@enricopiovesan
enricopiovesan merged commit bb17ba4 into main Aug 23, 2026
32 checks passed
@enricopiovesan
enricopiovesan deleted the claude/issue-1092-p2-parallel-scheduling branch August 23, 2026 07:23
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.

Implement P2 bounded deterministic parallel proposal scheduling

1 participant