Skip to content

Pause and resume browser optimization studies - #9606

Draft
kube wants to merge 4 commits into
claude/opt-proto-importancefrom
claude/opt-proto-pause-resume
Draft

Pause and resume browser optimization studies#9606
kube wants to merge 4 commits into
claude/opt-proto-importancefrom
claude/opt-proto-pause-resume

Conversation

@kube

@kube kube commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

Important

Experimental
Behind the In-browser optimization feature flag.

Summary

Before this PR, the only way to interrupt a browser study was Stop, which pruned the steps in flight and left them uncounted. Stopping and failing refined the best point on their own, so an interrupted study started computing before anyone asked.

This PR adds Pause. The Python loop asks the sampler for nothing more, awaits the evaluations in flight, tells and reports every one, and returns a paused summary; the worker posts paused and the segment ends with a paused event that keeps the study resumable. The record reads Paused at the click, the header counts the steps still finishing, every card takes the paused tone, and the footer offers Resume, which runs the steps the study still owes on the same sampler, and Run at the best configuration, with Remove in a More actions menu. Pausing, stopping and failing park the controls at the best step without computing anything there; only completion refines the best point on its own.

Links

Changes

Python

  • run_study takes is_paused and drains

    Once true the loop asks nothing more, keeps awaiting the evaluations in flight, tells and reports each and returns paused: True. Nothing is told failed.
    A pause detected after the last ask completes normally. Every summary carries paused.

  • run_browser_study takes is_paused as its sixth argument

    handle.requested settles on the told count, as after a stop.

Core browser runtime

  • paused event in the schema and pauseOptimizationRun on the connected capability

    The event carries the requested count, the three counts, best, resumable and seq. paused is terminal for a segment in the run log and a started may follow.

  • Worker drains on pause

    attach-optimizer-worker.ts keeps a paused set beside cancelled, passes isPaused to Python and posts paused when the summary says so. Pending evaluations keep their promises.

  • pauseOptimizationRun posts pause without aborting the segment's signal

    A pause asked of a run still waiting for the runtime is remembered and posted right after the segment starts, so Resume then owes the whole count. The paused message finishes the segment finished-resumable with the event.

  • browser/README.md segment diagram gains paused and a paragraph on who owns pausing

Provider

  • OptimizationStatus gains paused; pauseOptimization, resumeOptimization and refineOptimizationBest on the context

    markOptimizationPaused marks the record paused at the click with resumable false. The paused event sets the best, the counts and resumable. resumeOptimization extends by requestedTrials - trials.length and rejects when nothing is owed.

  • settleOnBest refines only on a complete outcome

    Paused, stopped and failed studies park the navigation at the best and empty the selection. refineBest() is the explicit refinement. A pause that drains a step which becomes the best parks there without refining.

Study view

  • Pause and Stop while a connected study is active; Resume, Run at the best configuration and More actions while paused

    Resume is disabled until the paused event lands and steps are owed. Run at the best configuration is offered on every paused, stopped, failed and complete connected study. No Restart anywhere.

  • Header reads "Paused at 12 of 30 steps · 1 step finishing" with a grey Paused chip

    The summary strip carries a note that resuming continues the history and a reload ends the paused study. The navigator says "nothing computed at this point" for a settled study with no selection.

  • Every chart card takes tone="paused" while paused

    The tone prop threads through the surface frame, the surface plot, the objective chart, the history chart, the Constraints card and the Sensitivity analysis card. The list badge for paused is grey with a pause icon.

  • Fixtures and stories Connected study, paused for the drawer and the full view

Known issues

  • Reloading the page ends a paused study

    Reload survival is designed in the research notes and not built here. The user docs say so.

  • Optimization service never emits paused

    The event is in the schema; apps/petrinaut-opt does not send it.

Next steps

  • Reload survival: prior trials replayed into a new Optuna study on mount
  • Paused-aware empty state for the objective chart

Test coverage

  • test_ask_tell.py, test_pyodide_entry.py:

    A pause with parallelism 2 tells and reports both in-flight trials with none failed and numbering continuing on resume, a pause after the last ask, a pause before the first ask, the browser handle's requested count.

  • optimization.test.ts, run-log.test.ts, attach-optimizer-worker.test.ts, browser-optimization.test.ts:

    The paused event schema, paused as a terminal followed by a started, the worker letting pending evaluations settle, a pause keeping the trial in flight and ending resumable, a pause on a queued run posted after start.

  • study-runner.pyodide.test.ts:

    The real Pyodide runtime with the isPaused callback.

  • connected-study.test.ts, provider.test.tsx:

    A stop settling on the best without refining and with a null selection, a pause draining the followed trial and parking at the best it reveals, refineBest climbing the ladder, Resume extending by the owed steps.

  • study-header.test.tsx, view-optimization-drawer.test.tsx:

    The paused header line and chip, Pause first beside Stop, every card in the paused tone, Resume and Run at the best configuration, Remove only in the menu, Resume held while a step is finishing.

  • Real Pyodide by hand:

    Storybook Simulate / Browser optimizer (real) supply-chain story with 12 steps, paused during step 4, resumed to Finished 12 steps.

How to test

In the browser

  • Open Petrinaut preview on Vercel
  • Viewport controls > Settings > Simulation > In-browser optimization
  • Load example > Supply Chain Profit
  • Simulate > Optimizations > Create
  • Select metric Profit, direction Maximize, tick Optimize production_rate, set Optimization steps to 12, Run
  • Open the study row

    Expect Pause as the first footer action and Stop beside it

  • Pause during step 4 or later

    Expect a Paused chip, the header reading "Paused at N of 12 steps · K steps finishing", every card greyed, Resume disabled

  • Wait for the steps in flight to land

    Expect the header without "finishing", Resume enabled, no refining batch in the activity list

  • More actions

    Expect Remove as the only item

  • Resume

    Expect the study to run on to "Finished 12 steps"

  • Run at the best configuration

    Expect the controls at the best step's point and runs refining there

Python

  • Run cd libs/@local/petrinaut-optimizer-core && uv run pytest -q

    Expect every test to pass

@vercel

vercel Bot commented Sep 9, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
hash Ready Ready Preview Sep 9, 2026 2:00pm UTC
petrinaut Ready Ready Preview Sep 9, 2026 2:00pm UTC
petrinaut-docs Ready Ready Preview Sep 9, 2026 2:00pm UTC
1 Skipped Deployment
Project Deployment Actions Updated
hashdotdesign-tokens Ignored Ignored Preview Sep 9, 2026 2:00pm UTC

Request Review

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/apps > hash.design Affects the `hash.design` design site (app) area/infra Relates to version control, CI, CD or IaC (area) area/libs Relates to first-party libraries/crates/packages (area) area/tests New or updated tests type/eng > backend Owned by the @backend team type/eng > frontend Owned by the @frontend team

Development

Successfully merging this pull request may close these issues.

1 participant