FE-1408: Run a trial as multiple seeded simulations aggregated by mean - #9223
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
1 Skipped Deployment
|
797689e to
ec38102
Compare
ec38102 to
8b4144f
Compare
PR SummaryMedium Risk Overview Seeds are fixed for the whole study via Docs ( Reviewed by Cursor Bugbot for commit c44a97d. Bugbot is set up for automated code reviews on this repo. Configure here. |
There was a problem hiding this comment.
Pull request overview
Adds deterministic multi-seed optimization trials to the Petrinaut CLI, aggregating replicate objectives by mean.
Changes:
- Runs sequential simulations using reusable derived seeds.
- Returns mean objectives and per-seed replicate results.
- Adds protocol, bundle, and unit coverage plus documentation.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
turbo.json |
Builds CLI before unit tests. |
optimization.ts |
Implements seeded trial evaluation and aggregation. |
optimization.test.ts |
Tests seeds, aggregation, and validation. |
transports.test.ts |
Tests multi-seed stdio responses. |
built-cli.test.ts |
Adds bundled CLI smoke test. |
README.md |
Documents multi-seed evaluation. |
OPTIMIZATION_INTEGRATION.md |
Documents protocol and seed derivation. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
8b4144f to
cbb5fca
Compare
47d6052 to
60028b5
Compare
60028b5 to
8b25fed
Compare
8b25fed to
0adc3b8
Compare
0adc3b8 to
3446864
Compare
Optimization trials run execution.seedsPerTrial seeded simulations
sequentially within one evaluate and aggregate the per-seed objectives
by mean. Seeds derive deterministically from execution.seed - replicate
0 keeps the base seed, later replicates reuse the Monte Carlo
derivation - and every trial reuses the same list, so Optuna compares
configurations under common random numbers. The evaluate response stays
{objective}-compatible and reports per-seed replicates; describe
reports seedsPerTrial. Parallelising the seeded runs is deferred to the
shared experiment-backend interface (FE-1341) so the CLI and the editor
share one worker story instead of a CLI-specific pool.
🌟 What is the purpose of this PR?
The CLI scores an optimization trial on one simulation, so a stochastic net is judged on a single sample. This PR runs each trial as
execution.seedsPerTrialseeded simulations and returns their mean.{ objective }shape, so the Python optimizer service needs no changes.Stack #9226: FE-1410 (contract) → FE-1411 (async protocol) → this PR → FE-1413 (arch-docs manual) → FE-1270 (Python bindings) → FE-1412 (Python timeout).
🔗 Related links
🔍 What does this change?
@hashintel/petrinaut-clionly:optimization.evaluateruns the trial's seeds one after another and returns:objective: the mean of the per-seed objectives;replicates: [{ seed, objective }], present whenseedsPerTrial > 1.optimization.describereportsstudy.seedsPerTrial.execution.seed, so one seed per trial behaves bit-identically to today and one editor run still reproduces a replicate;deriveRunSeed(seed, i)exported by FE-1410.seedsPerTrial.dist/cli.jsand checks a full describe/evaluate exchange, including a two-seed trial.🧪 Example
The manifest's
executionblock asks for three seeds per trial:Serve it and send one trial over stdio:
{ "id": 1, "method": "optimization.evaluate", "params": { "parameterValues": { "infected_ratio": 0.1 } } }The trial runs seeds 42, 1013904268 and 1520856381 in that order and answers with their mean:
{ "id": 1, "result": { "objective": 0.31, "replicates": [ { "seed": 42, "objective": 0.28 }, { "seed": 1013904268, "objective": 0.33 }, { "seed": 1520856381, "objective": 0.32 } ] } }Every trial reuses those three seeds, so repeating the request returns identical values. With
seedsPerTrial: 1(or the field omitted) the response is{ "objective": ... }alone, unchanged from today.Pre-Merge Checklist 🚀
🚢 Has this modified a publishable library?
This PR:
@hashintel/petrinaut-cliis private; the@hashintel/petrinaut-corechangeset landed with FE-1410)📜 Does this require a change to the docs?
The changes in this PR:
OPTIMIZATION_INTEGRATION.mdand the CLI README document the field, the seed derivation, and the response shape. The in-app user guide is untouched: the UI never setsseedsPerTrial, so in-app behaviour is unchanged until FE-1273's UI half lands.🕸️ Does this require a change to the Turbo Graph?
The changes in this PR:
turbo.json's have been updated to reflect thispetrinaut-cli'stest:unitnow depends on its ownbuild, so the smoke test always runs against a fresh bundle in CI.🐾 Next steps
seedsPerTrial.🛡 What tests cover this?
optimization.test.ts: mean aggregation, per-seedreplicates, identical seed list across trials, fail-fast on a non-finite replicate, extreme-value aggregation,deriveTrialSeedsrange and stability.transports.test.ts: multi-seed evaluate over stdio,seedsPerTrialin describe.built-cli.test.ts: spawns the real bundled CLI for the full exchange with two seeds.❓ How to test this?
turbo run test:unit --filter @hashintel/petrinaut-cli"seedsPerTrial": 4toexecutioninlibs/@hashintel/petrinaut-cli/examples/supply-chain-profit-optimization.json, runyarn workspace @hashintel/petrinaut-cli build, thennode libs/@hashintel/petrinaut-cli/dist/cli.js serve --optimization <manifest> --stdioand send anoptimization.evaluaterequest.objectiveplus fourreplicates; repeating the request returns identical values.🤖 Generated with Claude Code