FE-1485: Synthesize ad-hoc scenarios from an inline definition - #9284
Draft
kube wants to merge 2 commits into
Draft
FE-1485: Synthesize ad-hoc scenarios from an inline definition#9284kube wants to merge 2 commits into
kube wants to merge 2 commits into
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
1 Skipped Deployment
|
kube
force-pushed
the
cf/fe-1485-ad-hoc-scenario-synthesis-in-petrinaut-core
branch
2 times, most recently
from
August 22, 2026 16:50
21c1cd9 to
a25badb
Compare
An ad-hoc scenario is an initial-state + parameters definition made inline — per-place token spreadsheets whose cells are expressions, a Static or Dynamic count per place, and named Variables at two scopes — compiled into a Scenario value at run time and never persisted into the net file. Synthesis emits a code-mode scenario, the one initial-state mode whose expressions the existing compileScenario already evaluates in its hardened sandbox, so the compiler is untouched. synthesizeAdHocScenario ignores Optimize toggles and serves quick simulation and plain experiments. synthesizeAdHocOptimization turns every Optimize selection (cell, Variable, dynamic count, net parameter) into a generated scenario parameter with a deterministic source-derived name — the join key from optimization results back to what the user selected — and returns the manifest parameterBindings for them. Bounds are expressions that must resolve to constants at study creation; an optimized bound may not reference an optimized entity; per-place Variables evaluate per row, so they may read i. The tests round-trip every fabricated scenario through the real compileScenario.
kube
force-pushed
the
cf/fe-1485-ad-hoc-scenario-synthesis-in-petrinaut-core
branch
from
August 22, 2026 16:53
a25badb to
c83cb44
Compare
3 tasks
Top-level Variables are referenced as scenario.<name>, matching the scenario code editor. Synthesis emits AdHocSynthesisOutput (scenario + optimized fields with targets, labels, and domains) with adHocOptimizationBindings as the manifest transform. Adds slot keys and target labels for error and diagnostic attribution, the row-kind gutter cycle, place totals, and an ad-hoc LSP session that type-checks every value slot.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
🌟 What is the purpose of this PR?
The foundation of the ad-hoc scenario feature (FE-778): the shapes, the synthesis, and the expression type-checking infrastructure, all in
petrinaut-core. Bottom of stack #9286. The design follows the ratified prototype (the "shared column values" variation handed to the designers) and the decisions from the #lib-petrinaut thread of 2026-08-06.🔗 Related links
🔍 What does this change?
Three shapes, in pipeline order (
simulation/authoring/scenario/ad-hoc-scenario.ts):AdHocScenarioState— the form's editing state: per-place token spreadsheets whose every cell is an expression, rows that are Fixed or Dynamic and mix freely, shared column values, and Variables at two scopes. Rows cycle Fixed → Dynamic → count-Optimized throughcycleAdHocRowKind, retaining the count (bounds included) across the cycle.AdHocSynthesisOutput— what synthesis emits: a generated code-modeScenario(never persisted;compileScenariois untouched) plus oneAdHocOptimizedFieldper enabled Optimize toggle, carrying the deterministicadhoc.*parameter name, the source's attribution label (Space › item 0 › x), its target path, and its typed domain.output.scenariofeedscompileScenariodirectly (plain runs);adHocOptimizationBindings(output.optimizedFields)is the transform to aPetrinautOptimizationManifest'sparameterBindings(the manifest schema itself is unchanged).Expression vocabulary matches the scenario code editor: top-level Variables are written
scenario.<name>(they stand in for scenario parameters, exactly as in the Satellites Launcher example), per-place Variables are bare names, net parameters areparameters.<name>, andi/countare per row. Net parameter overrides may read top-level Variables.Slots (
AdHocSlot= target + part, with stable path-safeadHocSlotKeystrings) are the join key between synthesis errors, LSP diagnostics, and the form's rendering of both. Every synthesis error carries its slot.Place totals:
resolveAdHocPlaceTotalsums row counts — a number when everything resolves, the unresolved expressions printed otherwise — for the table's bottom line.LSP: a new ad-hoc session kind mirrors scenario sessions end to end (protocol notifications
temp/adhoc/*, virtual-file generation per non-empty value slot with scope-correct ambient declarations, service sync, worker handling, client methods). Every cell, count, Variable, net parameter override, and optimize bound gets a virtual TypeScript document type-checked as the slot's type; bounds see only the constant scope, soiin a bound is a type error.Pre-Merge Checklist 🚀
🚢 Has this modified a publishable library?
This PR:
patch).📜 Does this require a change to the docs?
The changes in this PR:
🕸️ Does this require a change to the Turbo Graph?
The changes in this PR:
🛡 What tests cover this?
24 synthesis tests — every fabricated scenario round-trips through the real
compileScenario, including thescenario.<name>vocabulary, optimize suggestions applied to every generated parameter kind, shared-column supersession, the gutter cycle's retention, place totals, slot keys, and attribution labels. 5 LSP-session tests pin scope-correct diagnostics (valid expressions acceptparameters.*/scenario.*/i/count/place variables; type mismatches and unknown identifiers report;iis out of scope in bounds; empty expressions produce no document; kill removes the session's files).❓ How to test this?
turbo run test:unit --filter @hashintel/petrinaut-core🐾 Next steps
FE-1486 (#9285) builds the form component on these shapes.
🤖 Generated with Claude Code