Can Your Agent Explore in Parallel Without Creating Chaos? Use Speculative Execution and Early Cancellation
Advanced Agents From First Principles 19: Can Your Agent Explore in Parallel Without Creating Chaos? Use Speculative Execution and Early Cancellation
A production agent often has more than one useful thing it could do next.
It could:
- inspect repository state,
- run a targeted test,
- retrieve documentation,
- ask a second model to critique a candidate,
- generate an alternative implementation,
- probe an API,
- inspect a deployment,
- or verify an invariant.
If those actions are independent, executing them one by one can be needlessly slow.
The obvious response is:
Run them in parallel.
That sounds simple.
It is not.
Parallel agent work introduces a new set of failure modes:
- duplicated work,
- conflicting side effects,
- stale observations,
- branches consuming budget after they are already dominated,
- cancellation that arrives too late,
- hidden tail latency,
- resource contention,
- verifier starvation,
- and race conditions between speculative branches and the real environment.
The central rule for this post is:
Parallelism is useful only when speculative work is isolated, independently valuable, and cheap enough to cancel when new evidence makes it unnecessary.
This is not merely a performance optimization.
It changes how an advanced agent allocates evidence gathering and search.
The sequential baseline
Suppose an agent is debugging a failing service.
A sequential runtime might do this:
inspect logs
↓
inspect recent commit
↓
run failing test
↓
search documentation
↓
generate fix candidate
↓
verify candidate
If each step takes several seconds, the whole critical path can become long even when the steps are mostly independent.
But some of them may not depend on one another.
For example:
inspect logs
/ | \
/ | \
inspect commit run test search docs
\ | /
\ | /
evidence
↓
decision
Now the decision may be reached as soon as enough evidence arrives.
That is the first important distinction:
Parallel systems optimize critical-path latency, not necessarily total work.
Running three probes concurrently can consume more total compute than running one probe first.
But if the probes are cheap and often decisive, latency may fall substantially.
The architecture must therefore track both:
wall-clock latency
and:
total resource consumption
Do not confuse them.
1. Speculation should happen before commitment
Parallelism is safest when branches are still informational or reversible.
Good speculative actions include:
- read-only repository inspection,
- test execution in isolated environments,
- log retrieval,
- documentation lookup,
- candidate generation,
- scoring,
- static analysis,
- sandboxed execution,
- dry runs,
- simulations,
- read-only API queries.
Dangerous speculative actions include:
- sending customer messages,
- deleting files,
- merging pull requests,
- changing production configuration,
- executing payments,
- restarting infrastructure,
- mutating shared databases,
- writing to shared external systems.
The architecture should therefore separate:
speculative phase
↓
selection
↓
commit phase
For example:
candidate A ── sandbox test ─┐
candidate B ── sandbox test ─┼─ select winner ── apply once ── verify
candidate C ── sandbox test ─┘
Not:
candidate A ── deploy
candidate B ── deploy
candidate C ── deploy
That second architecture is not exploration.
It is a race condition with production consequences.
2. Parallelism does not mean launch everything
Once concurrency exists, there is a temptation to fan out aggressively.
Suppose the agent can launch 20 observations at once.
It should not automatically do so.
Every branch has a cost:
model calls
+ tool calls
+ CPU/GPU time
+ external API usage
+ memory
+ context processing
+ verification work
The Step 16 budget scheduler still applies.
The Step 18 value-of-information policy still applies.
Parallelism changes only the scheduling geometry.
Instead of asking:
Which action should I run next?
The scheduler now asks:
Which small set of independent high-value actions should I run now?
That means ranking candidate actions by something like:
expected decision impact
------------------------
expected resource cost
and then selecting a bounded concurrent frontier.
3. Build a speculative frontier
A useful abstraction is a speculative frontier.
Each frontier item represents work that may be worth doing concurrently.
from dataclasses import dataclass, field
from typing import Callable, Any
@dataclass
class SpeculativeTask:
id: str
kind: str
expected_value: float
expected_cost: float
cancellable: bool
side_effect_class: str
dependencies: set[str] = field(default_factory=set)
run: Callable[[], Any] | None = None
The scheduler can then select tasks satisfying constraints such as:
no unmet dependencies
no unsafe speculative side effects
within concurrency budget
within resource budget
sufficient expected value
For example:
def eligible(task, completed):
return (
task.dependencies <= completed
and task.side_effect_class in {"read_only", "sandboxed", "reversible"}
)
This makes concurrency explicit rather than burying it inside asyncio.gather().
4. Concurrency needs a budget of its own
A system can satisfy the total token budget and still overload itself through parallelism.
You therefore need both:
total resource budget
and:
concurrency budget
For example:
@dataclass
class Budget:
max_model_calls: int
max_tool_calls: int
max_parallel_tasks: int
max_cost: float
max_wall_seconds: float
Why separate concurrency?
Because ten cheap tasks launched simultaneously can still:
- saturate rate limits,
- exhaust connection pools,
- overwhelm a local model server,
- spike memory,
- create queue contention,
- increase tail latency.
The scheduler must understand that:
cheap individually ≠ cheap concurrently
5. Measure the critical path
Suppose three probes take:
A = 2 seconds
B = 8 seconds
C = 5 seconds
Sequential time:
2 + 8 + 5 = 15 seconds
Parallel time if all are required:
max(2, 8, 5) = 8 seconds
But an advanced agent often does not need all results.
Suppose A and C together are enough to make the decision after 5 seconds.
Then B should be cancelled.
The critical path becomes:
5 seconds
while total work depends on how much of B was already consumed.
Useful metrics include:
critical_path_latency
aggregate_compute_time
cancelled_compute_time
useful_result_latency
wasted_speculation_cost
These are not interchangeable.
6. Early cancellation is the real optimization
Parallel fan-out without cancellation can easily become wasteful.
The important capability is not merely:
start many things
It is:
stop irrelevant things quickly
Imagine three candidate fixes:
A → tests fail immediately
B → tests still running
C → tests pass targeted checks
Once A fails, cancel its downstream analysis.
If C passes a strong acceptance cascade and dominates B under the selection policy, B may also be cancelled.
This suggests a branch lifecycle:
QUEUED
↓
RUNNING
↓
PARTIAL_RESULT
├─ CONTINUE
├─ CANCEL_DOMINATED
├─ CANCEL_BUDGET
├─ CANCEL_STALE
└─ COMPLETE
Cancellation should have explicit reasons.
That matters for observability and later policy learning.
7. Dominance is stronger than “looks worse”
Do not cancel branches merely because one internal score is slightly lower.
A branch is safely dominated only when the evidence is strong enough.
For example:
candidate A
verified targeted tests = PASS
cost remaining = low
candidate B
same targeted tests = FAIL
B is dominated.
But:
candidate A score = 0.73
candidate B score = 0.69
is weak evidence for cancellation unless the scorer is well calibrated.
A practical dominance rule may combine:
verified evidence
+ score margin
+ remaining expected value
+ remaining cost
+ uncertainty
The scheduler should be conservative when cancellation could remove the only eventual successful branch.
This is the parallel equivalent of pruning regret.
Call it:
cancellation regret
8. Cancellation regret
Suppose branch B is cancelled early.
Offline replay later shows B would have produced a verified success while the surviving branch failed.
That is a scheduler failure.
Define:
cancellation regret = value of best cancelled branch - value of selected branch
At the simplest level:
cancelled eventual PASS + selected FAIL
is a high-regret event.
Track:
cancelled branches
reason for cancellation
state when cancellation occurred
available evidence
counterfactual replay result
Without this lineage, early cancellation policies cannot improve safely.
9. Stale observations become more dangerous in parallel systems
Concurrency increases the chance that one observation is outdated by the time another branch uses it.
Example:
T0: branch A reads deployment state
T1: branch B performs isolated simulation
T2: external deployment changes
T3: branch C reads new deployment state
Now A and C disagree because they observed different states.
Do not treat this as a reasoning disagreement.
It may be a freshness problem.
Every observation should therefore carry:
state_id
observed_at
source
scope
freshness
For mutable environments, results may need a validity condition:
@dataclass
class Observation:
value: object
state_id: str
observed_at: float
valid_until: float | None
source: str
The runtime must detect when speculative evidence belongs to different environment versions.
10. State snapshots reduce races
When possible, run speculative work against an immutable snapshot.
Coding-agent examples:
git commit/tree hash
worktree snapshot
container image
locked dependency graph
Data-agent examples:
dataset version
snapshot timestamp
transaction snapshot
schema version
Browser-agent examples:
DOM snapshot
page version
request/response capture
Research-agent examples:
source IDs
retrieval timestamp
corpus version
The invariant is:
Branches being compared should ideally reason about the same underlying state.
Otherwise branch comparison becomes contaminated by environmental drift.
11. Isolation is more important than concurrency primitives
Using asyncio, threads, processes, or distributed workers is an implementation detail.
The architectural question is isolation.
Ask:
Can branch A affect branch B?
If yes, speculation is not clean.
Isolation can come from:
- separate worktrees,
- containers,
- transactions,
- temporary databases,
- copy-on-write filesystems,
- dry-run APIs,
- read-only credentials,
- namespaces,
- mocked external systems.
The more consequential the side effect, the stronger the isolation requirement.
12. Coding agent example: parallel repair branches
Suppose tests fail after a refactor.
The agent identifies three plausible strategies:
A: fix import boundary
B: revert interface change
C: update dependent call sites
A parallel architecture can create isolated worktrees:
base commit
├── worktree A → patch → targeted tests
├── worktree B → patch → targeted tests
└── worktree C → patch → targeted tests
Then rank branches by external evidence:
targeted test result
full relevant test result
lint/type checks
patch size
regressions
Only the selected branch is applied to the real working tree.
This is powerful because the speculative mutations are isolated.
Do not run all three patches directly against the same checkout.
13. Research agent example: parallel evidence probes
Suppose a claim depends on three possible evidence paths:
official source
primary paper
independent dataset
These can often run concurrently.
claim
├── official source retrieval
├── primary paper retrieval
└── dataset inspection
As soon as one authoritative source resolves the claim, weaker redundant retrieval may be cancelled.
But if the claim is contested, multiple independent sources may still have high value.
Parallelism therefore depends on the decision requirement.
The EVI policy from Step 18 remains the gating mechanism.
14. Browser agent example: parallel read-only discovery
A browser agent may need to discover:
- shipping cost,
- return policy,
- availability,
- compatibility.
Those are often independent read-only queries.
Parallel retrieval can reduce latency.
But the final checkout action must remain serial and verified.
parallel discovery
↓
compare options
↓
select
↓
confirm exact item / price / address
↓
commit action
↓
verify outcome
Speculation should not submit multiple purchases and cancel two afterwards.
15. Data-agent example: parallel validation probes
Before applying a transformation, a data agent can concurrently inspect:
schema compatibility
null-rate changes
distribution drift
referential integrity
sample output
If referential integrity fails immediately, more expensive downstream simulation may be cancelled.
This is a good example of early decisive evidence.
The branch scheduler should favor checks with high failure-detection value and low cost.
16. DevOps example: parallel diagnosis, serial remediation
During an incident, an agent might simultaneously inspect:
service logs
metrics
recent deploys
dependency health
queue depth
That is useful speculative observation.
But remediation should generally remain gated:
parallel diagnosis
↓
state synthesis
↓
proposed action
↓
precondition verification
↓
execute one remediation
↓
postcondition verification
Do not let five diagnostic branches independently restart five services.
17. Multi-agent systems need shared cancellation
Mixture-of-agents systems make this problem more visible.
Suppose a router launches:
code expert
research expert
critic
frontier model
If the code expert produces a verified deterministic solution in 800 ms, the other branches may no longer be worth their cost.
That requires a shared cancellation controller.
router
↓
launch specialists
↓
shared evidence bus
↓
selection / dominance policy
↓
cancel losers
Without shared state, every specialist runs to completion and the architecture becomes an expensive fan-out machine.
18. Partial results can be useful
A branch does not always need to finish before it becomes informative.
Examples:
test suite finds first deterministic failure
search branch discovers authoritative source
static analyzer reports invariant violation
critic identifies a verified regression
The runtime should surface partial results as events.
@dataclass
class BranchEvent:
branch_id: str
kind: str
evidence: dict
terminal: bool
The scheduler can react before branch completion.
That is what makes early cancellation effective.
19. Stragglers and tail latency
Parallel systems are often dominated by the slowest branch.
Suppose nine branches finish in 2 seconds and one takes 40 seconds.
If the system waits for all ten, parallelism did not solve the latency problem.
You need explicit policies for stragglers.
Possible rules:
cancel after decision becomes stable
cancel if expected remaining value falls below threshold
cancel if branch exceeds latency budget
cancel if equivalent evidence already arrived elsewhere
Do not use arbitrary timeouts as the only rule.
A slow branch may still be the only branch capable of resolving verification uncertainty.
Again, value matters more than elapsed time alone.
20. Hedged requests
A related technique is the hedged request.
If a tool or model endpoint occasionally has high tail latency, the runtime can start a second equivalent request after a delay.
request A starts
↓
latency threshold crossed
↓
request B starts
↓
first valid result wins
↓
cancel loser
This can reduce tail latency.
But it doubles work in some cases.
Use it only when:
- the action is read-only or idempotent,
- tail latency is materially expensive,
- duplicate execution is safe,
- cancellation works reliably.
Never hedge non-idempotent side effects casually.
21. Async execution skeleton
A minimal Python sketch:
import asyncio
from dataclasses import dataclass
@dataclass
class Result:
branch_id: str
score: float
verified: bool
payload: object
async def run_branch(branch):
return await branch()
async def speculative_execute(branches, accept):
tasks = {
asyncio.create_task(run_branch(branch)): i
for i, branch in enumerate(branches)
}
results = []
try:
for future in asyncio.as_completed(tasks):
result = await future
results.append(result)
if accept(result, results):
for task in tasks:
if not task.done():
task.cancel()
return result, results
return None, results
finally:
await asyncio.gather(*tasks, return_exceptions=True)
This is deliberately simple.
Production systems still need:
- resource accounting,
- cancellation reasons,
- branch lineage,
- state binding,
- side-effect classification,
- structured verification,
- timeout policy,
- retry policy,
- partial-result handling,
- cleanup.
The point is the control loop, not asyncio itself.
22. Cancellation is cooperative unless enforced
Calling task.cancel() does not magically stop every underlying operation.
A model API request may already be executing remotely.
A database query may continue.
A subprocess may survive.
A tool may ignore cancellation.
Therefore distinguish:
logical cancellation
physical cancellation
Logical cancellation means:
do not use this result anymore
Physical cancellation means:
stop consuming underlying resources
Track both.
Useful fields:
cancel_requested_at
cancel_acknowledged_at
work_stopped_at
post_cancel_cost
This reveals whether the cancellation mechanism actually saves resources.
23. Cleanup is part of correctness
Speculative branches create temporary resources.
Examples:
worktrees
containers
temporary files
database transactions
browser tabs
subprocesses
GPU jobs
network sessions
A cancelled branch must clean them up.
This suggests another invariant:
Cancellation is incomplete until speculative resources are either released or explicitly transferred to the selected branch.
Otherwise long-running agents accumulate invisible state.
24. Do not starve verification
Parallel search can consume a budget extremely quickly.
Suppose the system has 20 model-call credits.
Launching 20 speculative candidates immediately leaves nothing for verification.
The protected verification reserve from Step 16 becomes even more important under concurrency.
For example:
total budget = 20
verification reserve = 4
max speculative allocation = 16
But even that may be too permissive.
The scheduler should also limit concurrent speculative consumption.
max in-flight model calls = 4
This preserves both budget and responsiveness.
25. Parallel search vs beam search
Parallel execution is not the same as beam search.
Beam search defines a selection strategy over branches.
Parallel execution defines an execution strategy.
You can have:
beam search executed sequentially
or:
beam search with parallel branch expansion
Similarly, MCTS can parallelize rollouts.
The distinction matters because benchmarking should isolate:
search policy gain
from:
concurrency gain
Do not claim a search algorithm is better when the real improvement came from parallel wall-clock execution.
26. Benchmark concurrency fairly
Compare at least:
A. sequential single best action
B. sequential EVI-ranked actions
C. fixed-width parallel speculation
D. adaptive parallel speculation + cancellation
Keep the same maximum resource envelope.
Measure:
verified success
p50 latency
p95 latency
aggregate cost
cost per verified success
cancelled cost
post-cancel cost
cancellation regret
verification starvation
If parallelism reduces latency but doubles cost, that tradeoff should be visible.
If adaptive cancellation recovers most of the latency gain while avoiding most of the extra work, that is evidence the policy is useful.
27. Measure useful concurrency
A useful metric is:
useful_concurrency_ratio
=
parallel tasks that contributed unique decision-relevant evidence
/
parallel tasks launched
If the runtime launches eight branches and seven produce redundant evidence, concurrency is mostly waste.
Also track:
redundant_result_rate
cancel_before_use_rate
cancel_after_use_rate
straggler_rate
resource_contention_rate
These metrics expose fan-out architectures that look sophisticated but contribute little.
28. Concurrency can reduce reliability
Parallelism does not automatically preserve correctness.
Potential failure modes include:
- comparing branches built from different state snapshots,
- selecting the first result rather than the best result,
- race-dependent output,
- non-deterministic shared memory updates,
- duplicate writes,
- cancellation before sufficient verification,
- stale partial evidence,
- conflicting cleanup.
A useful test is:
same task
same state snapshot
same policy
vary scheduling order
If outcomes change materially because completion order changed, the runtime has schedule sensitivity.
Track it.
29. Schedule sensitivity
Define:
schedule sensitivity
=
probability that different valid completion orders produce different selected outcomes
This is especially important when branch selection uses “first acceptable result wins”.
A first-result policy may introduce hidden quality regressions.
Compare:
first acceptable
best after short grace period
best after evidence threshold
best under fixed wall-clock budget
The fastest policy may not be the best reliability-cost tradeoff.
30. Grace periods can improve selection
Suppose candidate A passes after 900 ms.
Candidate B is likely to finish within another 100 ms.
Immediately cancelling B may save almost nothing while risking cancellation regret.
A small grace period can sometimes improve selection:
first strong result
↓
short grace window
↓
collect near-complete competitors
↓
select
↓
cancel rest
Do not hard-code this universally.
Learn or calibrate it from trajectory evidence.
31. Parallel verification can also help
Verification itself may contain independent checks.
A coding change might need:
unit tests
static analysis
type checking
security scan
integration test
Some checks can run concurrently.
But verification policy still matters.
For example:
cheap deterministic checks first
↓
if they pass
↓
parallel expensive checks
This can dominate launching every expensive verifier immediately.
Again, concurrency should follow value and dependency structure.
32. Progressive fan-out
One useful strategy is progressive fan-out.
Start with a small number of high-value branches.
Expand only when uncertainty remains high.
launch 2 branches
↓
enough evidence?
yes → decide
no → launch 2 more
↓
reassess
This avoids paying full fan-out cost on easy tasks.
It also integrates naturally with Step 16’s scheduler and Step 17’s uncertainty decomposition.
33. Adaptive concurrency
Instead of a fixed parallel width, choose width from the task state.
Possible signals:
candidate uncertainty
route uncertainty
expected branch diversity
cost budget
latency requirement
model/tool capacity
historical rescue rate
Easy task:
parallel width = 1
Ambiguous but cheap task:
parallel width = 3
High-cost or high-risk task:
parallel width = 1 or 2
verification reserve = high
The scheduler should not confuse “hard” with “launch everything”.
34. Backpressure matters
An agent can produce speculative work faster than workers can consume it.
Without backpressure:
planner generates branches
↓↓↓↓↓↓↓↓↓↓↓↓↓
queue grows indefinitely
↓
memory / cost / latency explode
A production runtime needs queue limits.
max queued branches
max in-flight branches
max unresolved partial results
When the queue is full, the planner must stop generating more work.
This is systems engineering, not prompt engineering.
35. Parallelism should preserve provenance
Every result should retain:
branch_id
parent_state_id
snapshot_id
policy_version
started_at
completed_at
cancelled_at
resource_cost
result_hash
verification_status
Otherwise the system cannot reconstruct which evidence came from which speculative state.
This matters for:
- debugging,
- replay,
- attribution,
- policy learning,
- cancellation regret,
- safety audits.
36. A branch result is not automatically current truth
A speculative branch may discover something valid about its snapshot.
That does not mean the observation remains valid when the real environment changes.
Before acting on speculative results, revalidate critical assumptions against current state.
For example:
candidate patch passed on snapshot X
↓
current main still equals X?
↓
if yes → apply
if no → rebase / rerun / invalidate
This preserves the source-of-truth discipline from earlier posts.
37. Speculation should reduce uncertainty, not create it
A bad parallel architecture produces many conflicting outputs and leaves the runtime more confused.
A useful speculative branch should do at least one of these:
reduce uncertainty
eliminate an option
verify an invariant
produce a candidate
strengthen evidence
expose a failure
If branches consistently produce unstructured opinions that cannot be compared, parallelism only multiplies ambiguity.
That is not useful exploration.
38. Failure taxonomy
Useful failure labels include:
SPECULATION_SIDE_EFFECT_LEAK
SNAPSHOT_MISMATCH
CANCELLATION_REGRET
CANCELLATION_NOT_ENFORCED
STRAGGLER_WAIT
VERIFY_STARVED
REDUNDANT_FANOUT
RESOURCE_CONTENTION
SCHEDULE_SENSITIVE_SELECTION
STALE_PARTIAL_RESULT
CLEANUP_FAILURE
BACKPRESSURE_FAILURE
These labels make concurrency failures measurable rather than anecdotal.
39. Failure injection
Test the runtime deliberately.
Inject cases where:
- one branch hangs,
- one branch returns a fast wrong answer,
- one branch ignores cancellation,
- two branches produce duplicate evidence,
- environment state changes mid-run,
- a cancelled branch leaks a temporary resource,
- a verifier becomes slow,
- one branch exceeds budget,
- a rate limit reduces effective concurrency.
Then verify that the scheduler:
cancels correctly
preserves verification reserve
avoids stale evidence
cleans resources
stays within budget
returns UNKNOWN when necessary
Do not wait for production to discover these races.
40. Parallelism changes observability
Step 13’s trajectory observability now needs concurrency-aware events.
For example:
BRANCH_LAUNCHED
BRANCH_PARTIAL_RESULT
BRANCH_DOMINATED
CANCEL_REQUESTED
CANCEL_ACKNOWLEDGED
BRANCH_COMPLETED
BRANCH_DISCARDED_STALE
RESOURCE_RELEASED
And traces should be represented as a DAG, not a flat sequence.
That allows you to reconstruct the true critical path.
41. Learn cancellation policy from verified trajectories
Once these events are recorded, Step 14’s trajectory-learning loop can improve cancellation.
Useful questions include:
Which evidence patterns safely predicted domination?
Which cancellations caused regret?
Which branches rarely contributed unique evidence?
Which tools ignored cancellation?
Where did concurrency reduce p95 latency?
Where did it only increase cost?
Then candidate policies can be evaluated offline before promotion.
Do not let the runtime self-modify cancellation thresholds directly from the latest run.
Use the same held-out, shadow, canary, rollback discipline as other control policies.
42. The simplest parallelism often wins
You do not need a distributed agent framework to benefit from this idea.
A small runtime may only need:
2 concurrent diagnostic tool calls
1 isolated candidate branch
1 protected verifier
That may deliver most of the latency benefit without introducing a large orchestration layer.
Remember the series rule:
Complexity is not a capability ladder.
Parallelism must earn its operational cost.
43. Decision guide
Use parallel speculation when:
multiple actions are independent
and
results are comparable
and
side effects are isolated
and
latency matters
and
cancellation can save meaningful work
Prefer sequential execution when:
steps have strong dependencies
or
state mutates between actions
or
work is already cheap
or
side effects are difficult to isolate
or
rate limits make concurrency ineffective
Use progressive fan-out when:
task difficulty varies significantly
Use hedging when:
a read-only/idempotent dependency has expensive tail latency
44. The complete advanced control loop
The architecture developed across the recent posts now looks like this:
request
↓
observe exact state
↓
decompose uncertainty
↓
identify pending decision
↓
rank information/actions by expected value
↓
allocate shared compute budget
↓
launch bounded speculative frontier
↓
collect partial evidence
↓
cancel dominated / stale / low-value work
↓
select branch
↓
revalidate current state
↓
commit controlled side effect
↓
external verification
↓
PASS / FAIL / UNKNOWN
↓
trajectory log
↓
offline policy learning
That is a very different architecture from:
prompt → LLM → tool → repeat
The intelligence is increasingly in the runtime control structure.
45. Final principle
The temptation with parallel agents is to equate concurrency with capability.
Do not.
The useful question is:
Which independent work can I safely speculate on now, and how quickly can I stop paying for branches once evidence says they no longer matter?
That gives us the governing rule:
Parallelize independent, low-risk, high-value work; isolate speculative state; cancel aggressively when evidence is strong; and commit side effects only after selection and revalidation.
The next stage is a natural consequence of this architecture:
distributed coordination and leases — what happens when speculative branches and agent workers no longer live inside one process and cancellation, ownership, retries, idempotency, and exactly-once illusions become distributed-systems problems.