Skip to content

feat(migrate): run configurations, property-valued probabilities, draw policies and a result comparison harness - #383

Merged
HuiJun merged 66 commits into
developfrom
feature/v1-simulation-configs
Sep 20, 2026
Merged

HuiJun merged 66 commits into
developfrom
feature/v1-simulation-configs

Conversation

@devin-ai-integration

@devin-ai-integration devin-ai-integration Bot commented Sep 18, 2026

Copy link
Copy Markdown
Contributor

What and why

The SysML v1 migrator wrote a decision edge's «Probability» as a constant even when the tag names a property of the analysis block, so every migrated run drew a fixed tier mix instead of the one a Cameo run configuration sets; the SimulationProfile:SimulationConfig elements themselves (run count, duration mode, time variable, execution target, result location) and the tool's stored result snapshots were reported unmapped, and nothing compared a migrated configuration's -runs distribution with those snapshots.

  • Property-valued «Probability». activity.go: probability() resolves a tag that names a property (by name or XMI id) visible from the activity or its context block to a feature reference, @Probability { p = ProbabilityBTOOP; }, so the object the behavior runs on decides the weights. Tags naming nothing visible, a private property, a non-property or a non-numeric one are report entries with the reason. Lowering type-checks a feature-valued p against Probability::p, and the [0, 1] / sum-to-one checks made of constants at lowering are made of the read values when the decision is reached, each an ErrBranchWeights; guarded-out branches are filtered before the draw and the rest renormalised.
  • Draw policy. runtime.DrawPolicy (random|min|max|average) states how every RandomFunctions call resolves — min/max/average need no seed, normal has no finite min/max and returns a typed error naming the call. Threaded like the seed: -draws, %draws, %runs <n> [<seed>] <action> (seed optional under a fixed policy, still refused under random), analysis wire/JSON ("draws"), external and standing engines, gRPC, witnesses (draws by max) and replay: compatibility. Weighted decisions stay seeded whatever the policy.
  • SimulationConfig → v2. simconfig.go writes each configuration, recognised by its profile's provenance, as an action def holding the executionTarget as part target and perform action run ::> target.<behavior> (inherited classifier behaviors resolved), annotated with the new non-normative OpenSysML Libraries/Simulation.sysml metadata @Simulation::Configuration { runs; draws; timeVariable; startTime; stepSize; timeUnit; parallelForks }; every other setting is kept in a comment. Targets the migration did not write, non-part targets, state machines and classifiers with no behavior are reported with the reason. ActionExecutor.Results() also exposes <part>.<attribute> of the parts the action holds so the target's attributes are observable after the run.
  • Results and the harness. results.go indexes the tool's result-snapshot instances (classifier-less or typed) under each configuration's resultLocation/result package into a JSON sidecar (-migration-results <file>), resolving observable names through defining features and inferring classifiers from slot owners. Snapshots in a shared result package whose configured feature values differ from what the target configures are excluded with a note rather than mixed in. sysml <migrated>.sysml -compare-results <sidecar> [-action ...] [-runs n] [-draws p] [-seed s] [-observe stored[=feature]...] runs each configuration with its recorded count and policy (or the ones given) and prints tool vs OpenSysML min/mean/p50/p90/max per observable with the relative difference; empty, non-numeric and unrun observables are reported, never dropped.
  • Report hygiene. SimulationConfig elements, their target and result instances and the represented «Probability» edges are mapped where written.
  • A profile namespace ending in .xmi (SimulationProfile.xmi) is pinned as a profile, not the OMG XMI namespace, by tests in internal/translate/xmi and its sysmlv1 reader.
  • The sidecar schema is the new package internal/translate/simresults (standard library imports only), registered in the translate layer of tests/hygiene/layering_test.go: it describes what the migration writes, and migrate, the CLI and the REPL comparison read it through that layer; no permitted or tolerated entry changed.
  • Two runtime fixes the configurations needed: a performed feature chain joins the performance its object already runs, and a parallel region stood for by a stateless state needs no initial.
  • The self-model, README and testing notes count 104 bundled library files / ten extensions; the pilot-differential baseline differs from develop's in the examples/ digest only, re-recorded for that figure.

TMT proof (TMT-2024x.mdzip)

total mapped approximated unmapped skipped
develop 44604 27943 10285 6376 1713
this branch 44604 27967 10261 6376 1713

The +24 mapped / −24 approximated is 24 SimulationConfig classes (of 62, all approximated as plain classes before) and 6 decision nodes becoming mapped, against 6 unmarked control flows beside marked ones now reported approximated with the complementary weight they are given; no other report entry moves. The 38 remaining configurations are approximated with the reason (12 name no execution target, the classifier behavior of the target is written as a verification def rather than an action def, treatAllClassifiersAsActive = false, …). The migrated file validates with 0 errors. 30 of the 62 configurations have stored snapshots (82 total).

Acquire Target with IRIS and NFIRAOS - Logical, seed 1, Time_Acq_Total:

configuration tool runs tool mean OpenSysML runs OpenSysML min / mean / p50 / p90 / max
Group 0 (recorded 1000 runs) 4 16.46 s 1000 3.00 / 21.33 / 19.22 / 39.76 / 91.83 s
Group 0 4 16.46 s 100 3.16 / 21.55 / 19.90 / 39.17 / 78.75 s
Group 1 4 157.21 s 100 42.50 / 103.05 / 92.40 / 153.27 / 227.57 s
Group 3 1 208.4 s 100 51.12 / 117.70 / 105.58 / 186.81 / 331.51 s
Group 6 1 210.4 s 100 45.97 / 117.71 / 107.63 / 195.81 / 310.44 s

For comparison, develop's migration of the same activity (fixed p = 0.5) gives mean 133.31 s (30.86–315.42 s) at 100 runs. The Group 0 target class as saved in the model configures only ProbabilityAcqPwfsSecond = 1.0; the four stored snapshots recording that configuration are the ones compared, and the nine others in the shared Results::Group 0 package (six recording AcqTelPoint = BTOOP = ChkLaserProp = 1.0, mean 96.6 s, and three recording AcqTTFOIWFS = 1.0) are excluded with a note as runs of another configuration. Under -draws max, Align BTO OP Logical on its target is 90.2 s for every run (min 9.2 s, average 49.7 s).

Known limitations

  • The remaining gap to the tool's numbers on the acquisition workflow is the opaque JavaScript retry loop in Acquire and Lock PWFS Logical, which is migrated by another change; it also makes the Group 0 configuration exceed the action-step budget under a fixed draw policy, so the deterministic-duration proof uses Align BTO OP Logical.
  • The «SimulationConfig» settings other than the seven metadata fields (executionListeners, animationSpeed, UI options, …) are kept in a comment and are not executable.
  • The sidecar's snapshot values are the tool's; a snapshot slot defined outside the document (MonteCarloAnalysis::Mean, …) or holding a non-number is a note, not a value.
  • A target property whose default literal is empty configures nothing: it is read as an unspecified value the run fills, so it neither filters snapshots nor is compared.

Specification basis

SysML v2 v2.0 §7.16 (Actions: decision nodes and succession guards) for the weighted-successor semantics; the «Probability» tag, SimulationConfig, result snapshots and durationSimulationMode are MagicDraw/Cameo profile encodings with no OMG counterpart, migrated by provenance. docs/project/spec-compliance.md gains rows for the draw policy and non-constant branch weights; docs/reference/sysml-v1-migration.md gains the mapping rows and a "Run configurations" section.

How it was verified

  • gofmt -l . (empty), go vet ./..., make lint, go build ./..., go test ./... (incl. ./tests/...) all pass locally.
  • Corpus gates with the corpora downloaded (OPENSYSML_REQUIRE_TRAINING_CORPUS=1 OPENSYSML_REQUIRE_PILOT_CORPORA=1 OPENSYSML_REQUIRE_PILOT_LIBRARY_XMI=1 go test -count=1 ./tests/corpus ./tests/identity -run 'TestTrainingExamples|TestPilotCorpora|TestPilotLibraryXMI|TestCorpusGates|TestCorpusRoundTrip'): 100/100 training clean, pilot ratchets unchanged, 9823 identities agree.
  • make docs-check, python3 scripts/changelog.py check, python3 scripts/check-doc-ids.py pass.
  • New coverage: migrate fixtures under tests/migrate (testdata/xmi/simconfig.xmi) (property-valued probability, config → action def, min/max/random/average modes, result snapshots incl. classifier-less, nested packages, other-configuration exclusion, empty defaults); conformance stochastic_draws_{min,max,average}, stochastic_draws_max_normal_unbounded, stochastic_weights_read_from_performer, action_part_attributes_in_outcome, action_perform_chain_joins_object_performance, state_parallel_stateless_region (+ trace goldens); robustness_draw_policy_test.go; REPL/CLI/analysis/gRPC/witness tests for -draws/%draws/replay; cmd/sysml/compare_test.go for the harness; internal/translate/xmi namespace tests; go test ./tests/... incl. the layering gate.
  • By hand: the TMT migration and runs above; the migrated model validates with 0 errors.

Checklist

  • make test and make lint pass locally
  • Tests added or updated for the change
  • Documentation extended where it already covers the surface (see CONTRIBUTING.md)
  • Changelog entry added as changes/unreleased/<slug>.<section>.md, not as an edit to CHANGELOG.md
  • baselines regenerated and make docs-counts run if a gate count moved (compliance rows need nothing: the census is counted at docs build)
  • No internal work-item labels (waves, slices, F4, K5) in the body, docs, or changelog

devin-ai-integration Bot and others added 15 commits September 17, 2026 21:29
-draws / %draws resolve every uniform, uniformInteger, triangular and normal
call at random from the seed, or at the call's min, max or average, threaded
through the analysis questions, the engine wire and witnesses so replay: follows it.

Co-Authored-By: jason.han <hanhuijun@gmail.com>
…ferences

A «Probability» naming a numeric property visible from the activity is written
as a reference the run reads at the decision, not folded to its default; the
unmarked branch takes the dynamic remainder. Metadata bodies are type-checked
so a feature-valued weight must be Real or Integer, and the runtime checks the
declared distribution's range and sum when the decision is reached.

Co-Authored-By: jason.han <hanhuijun@gmail.com>
…stant ones

Co-Authored-By: jason.han <hanhuijun@gmail.com>
…w policy

Co-Authored-By: jason.han <hanhuijun@gmail.com>
…ject already runs

Co-Authored-By: jason.han <hanhuijun@gmail.com>
… initial

Co-Authored-By: jason.han <hanhuijun@gmail.com>
…ing the target's behavior

Co-Authored-By: jason.han <hanhuijun@gmail.com>
Co-Authored-By: jason.han <hanhuijun@gmail.com>
…re each configuration's runs with them

-migration-results writes the run configurations and their stored snapshots
as a JSON sidecar; -compare-results runs each configuration on its target for
its numberOfRuns under its durationSimulationMode and prints the tool's and
OpenSysML's min, mean, p50, p90 and max per observable with the relative
difference. An action's outcome now holds what the one object each of its
parts denotes holds, as part.attribute, so a configuration's observables are
read off its target; %runs takes no seed under a fixed draw policy.

Co-Authored-By: jason.han <hanhuijun@gmail.com>
…on the wire

Co-Authored-By: jason.han <hanhuijun@gmail.com>
…ults comparison

Co-Authored-By: jason.han <hanhuijun@gmail.com>
…d result package

Co-Authored-By: jason.han <hanhuijun@gmail.com>
The self-model, README and testing notes now state 104 bundled library files and
ten OpenSysML extensions; the pilot-differential digest of examples/ is re-recorded
for the self-model's new figure.

Co-Authored-By: jason.han <hanhuijun@gmail.com>
@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

@devin-ai-integration
devin-ai-integration Bot marked this pull request as ready for review September 18, 2026 02:02
devin-ai-integration[bot]

This comment was marked as resolved.

…car trailing content

A metadata value must be model-level evaluable, except the weight
Stochastic::Probability::p, which the run reads when its decision is
reached; every other metadata feature, including p on another type, keeps
the rule. ReadResults now requires the sidecar to hold exactly one JSON
document and rejects a second document or trailing garbage.

Co-Authored-By: jason.han <hanhuijun@gmail.com>
devin-ai-integration[bot]

This comment was marked as resolved.

devin-ai-integration Bot and others added 3 commits September 18, 2026 02:36
…ads it

A subtype of Stochastic::Probability has no runtime reader, so its
inherited p is judged model-level evaluable like any metadata value.

Co-Authored-By: jason.han <hanhuijun@gmail.com>
…ion-configs

The pilot-differential digest of examples/ is re-recorded for the merged tree; both sides had re-recorded it for their own self-model figures.

Co-Authored-By: jason.han <hanhuijun@gmail.com>
…ion-configs

The embedded library snapshot is regenerated for the merged bundled library.

Co-Authored-By: jason.han <hanhuijun@gmail.com>
devin-ai-integration[bot]

This comment was marked as resolved.

devin-ai-integration Bot and others added 2 commits September 18, 2026 07:09
…etadata body literal, fix normal(m, 0) under min and max

A -compare-results configuration some runs of which failed is now a failing verdict with each error under the table, as a %runs table with a failed row is; the header still counts the completed runs the statistics are of.

A metadata body value the model can evaluate is checked against the restated feature's scalar type like any other: @weight { p = "heavy"; } on a Real p is a type error. The DiagramLayout pass keeps judging constants of the right type that are no geometry (null, an odd pair).

normal(mean, 0) draws nothing but mean, so min and max resolve it to mean as average does; a normal with sd > 0 stays unbounded under them.

Co-Authored-By: jason.han <hanhuijun@gmail.com>
Co-Authored-By: jason.han <hanhuijun@gmail.com>
devin-ai-integration[bot]

This comment was marked as resolved.

…state needs no initial

The exemption a parallel state's regions already had applies to the machine's top-level regions too: a bare `state idle;` beside a region with substates is a region standing in idle, not one missing its `entry; then <state>;`. The robustness case for a region without an initial now declares substates, since the bare state it used is a valid region.

Co-Authored-By: jason.han <hanhuijun@gmail.com>
…config branch

Co-Authored-By: jason.han <hanhuijun@gmail.com>
devin-ai-integration[bot]

This comment was marked as resolved.

…ding it

Co-Authored-By: jason.han <hanhuijun@gmail.com>
devin-ai-integration[bot]

This comment was marked as resolved.

devin-ai-integration Bot and others added 2 commits September 19, 2026 01:06
…ted slots

Co-Authored-By: jason.han <hanhuijun@gmail.com>
…ion-configs

Co-Authored-By: jason.han <hanhuijun@gmail.com>

# Conflicts:
#	docs/project/pilot-differential-baseline.json
devin-ai-integration[bot]

This comment was marked as resolved.

devin-ai-integration Bot and others added 2 commits September 19, 2026 04:41
An explicitly empty -compare-results= was indistinguishable from the flag's
absence, so the model alone ran and the REPL opened; an empty
-migration-results= silently wrote no sidecar. Both are usage errors now,
beside the other empty-value checks.

Co-Authored-By: jason.han <hanhuijun@gmail.com>
…ion-configs

Co-Authored-By: jason.han <hanhuijun@gmail.com>

# Conflicts:
#	README.md
#	cmd/sysml/check.go
#	cmd/sysml/convert.go
#	docs/internals/testing.md
#	docs/project/pilot-differential-baseline.json
#	docs/reference/grammar/README.md
#	examples/self-model/pipeline.sysml
#	internal/check/passes/typecheck_metadata_body.go
#	internal/check/passes/typecheck_metadata_body_test.go
#	internal/exec/runtime/action_results_parts_test.go
#	internal/exec/runtime/draw_policy.go
#	internal/exec/runtime/draw_policy_test.go
#	internal/exec/runtime/modeled.go
#	internal/exec/runtime/robustness_draw_policy_test.go
#	internal/exec/runtime/robustness_feature_weights_test.go
#	internal/exec/runtime/testdata/conformance/action_part_attributes_in_outcome.expected.json
#	internal/exec/runtime/testdata/conformance/action_part_attributes_in_outcome.sysml
#	internal/exec/runtime/testdata/conformance/action_perform_chain_joins_object_performance.expected.json
#	internal/exec/runtime/testdata/conformance/action_perform_chain_joins_object_performance.sysml
#	internal/exec/runtime/testdata/conformance/state_parallel_stateless_region.expected.json
#	internal/exec/runtime/testdata/conformance/state_parallel_stateless_region.sysml
#	internal/exec/runtime/testdata/conformance/state_parallel_stateless_region.trace.golden
#	internal/exec/runtime/testdata/conformance/state_parallel_stateless_region_with_behaviors.expected.json
#	internal/exec/runtime/testdata/conformance/state_parallel_stateless_region_with_behaviors.sysml
#	internal/exec/runtime/testdata/conformance/state_parallel_stateless_region_with_behaviors.trace.golden
#	internal/exec/runtime/testdata/conformance/state_parallel_stateless_top_region.expected.json
#	internal/exec/runtime/testdata/conformance/state_parallel_stateless_top_region.sysml
#	internal/exec/runtime/testdata/conformance/state_parallel_stateless_top_region.trace.golden
#	internal/exec/runtime/testdata/conformance/stochastic_draws_average.expected.json
#	internal/exec/runtime/testdata/conformance/stochastic_draws_average.sysml
#	internal/exec/runtime/testdata/conformance/stochastic_draws_max.expected.json
#	internal/exec/runtime/testdata/conformance/stochastic_draws_max.sysml
#	internal/exec/runtime/testdata/conformance/stochastic_draws_max.trace.golden
#	internal/exec/runtime/testdata/conformance/stochastic_draws_max_normal_unbounded.expected.json
#	internal/exec/runtime/testdata/conformance/stochastic_draws_max_normal_unbounded.sysml
#	internal/exec/runtime/testdata/conformance/stochastic_draws_min.expected.json
#	internal/exec/runtime/testdata/conformance/stochastic_draws_min.sysml
#	internal/exec/runtime/testdata/conformance/stochastic_weights_read_from_performer.expected.json
#	internal/exec/runtime/testdata/conformance/stochastic_weights_read_from_performer.sysml
#	internal/frontend/repl/compare.go
#	internal/frontend/repl/compare_test.go
#	internal/frontend/repl/draws_test.go
#	internal/frontend/repl/runs.go
#	internal/semantic/semantics/stochastic.go
#	internal/translate/convert/convert.go
#	internal/translate/migrate/migrate.go
#	internal/translate/migrate/results.go
#	internal/translate/migrate/simconfig.go
#	internal/workspace/libs/stdlib/OpenSysML Libraries/Simulation.sysml
#	tests/hygiene/layering_test.go
devin-ai-integration[bot]

This comment was marked as resolved.

devin-ai-integration Bot and others added 2 commits September 19, 2026 20:41
Both sides re-recorded the examples digest of the pilot differential baseline; it is re-derived over the merged tree.

Co-Authored-By: jason.han <hanhuijun@gmail.com>
Co-Authored-By: jason.han <hanhuijun@gmail.com>
devin-ai-integration[bot]

This comment was marked as resolved.

…bservable

Co-Authored-By: jason.han <hanhuijun@gmail.com>
devin-ai-integration[bot]

This comment was marked as resolved.

devin-ai-integration Bot and others added 2 commits September 19, 2026 21:28
… path only

Co-Authored-By: jason.han <hanhuijun@gmail.com>
Co-Authored-By: jason.han <hanhuijun@gmail.com>
devin-ai-integration[bot]

This comment was marked as resolved.

@devin-ai-integration
devin-ai-integration Bot added this pull request to stack #455 September 19, 2026 21:38
…ts it by simple name

A quoted unrestricted name may hold '::', so the sidecar name Cfg::'Sub::Group'
ends in the one segment 'Sub::Group'; splitting the flat text on the last '::'
made -action Sub::Group select nothing. The selector and the configuration's name
are now read through the notation parser, segment by segment.

Co-Authored-By: jason.han <hanhuijun@gmail.com>
devin-ai-integration[bot]

This comment was marked as resolved.

…at both ends

uniform(lo, hi) draws on [lo, hi) at random, and max resolves it to hi: the bound
the draws approach, as a v1 duration interval's tool reads its max mode.

Co-Authored-By: jason.han <hanhuijun@gmail.com>
devin-ai-integration[bot]

This comment was marked as resolved.

devin-ai-integration Bot and others added 3 commits September 19, 2026 22:25
…r, a general or a special of it

A snapshot classified by a sibling special — sharing only a general with the
target's classifier — is of a run on another kind of object, and a shared
result package no longer mixes its snapshots into the configuration's results.
The classifier test reads the conformance direction: the snapshot's classifier
is among the target's classifiers and their generals, or its own generals
reach one of the target's classifiers.

Co-Authored-By: jason.han <hanhuijun@gmail.com>
…ion-configs

Co-Authored-By: jason.han <hanhuijun@gmail.com>

# Conflicts:
#	internal/ir/lower/state_graph.go
#	internal/translate/migrate/migrate.go
…ion-configs

Co-Authored-By: jason.han <hanhuijun@gmail.com>

# Conflicts:
#	cmd/sysml/usage.go
#	internal/frontend/repl/meta.go
#	man/man1/sysml.1
devin-ai-integration[bot]

This comment was marked as resolved.

…aults

Co-Authored-By: jason.han <hanhuijun@gmail.com>
@HuiJun
HuiJun merged commit 2bc543d into develop Sep 20, 2026
12 checks passed
@HuiJun
HuiJun deleted the feature/v1-simulation-configs branch September 20, 2026 02:14
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.

1 participant