Skip to content

test(runtime): pin a state's entry, do and exit actions as one performance each - #1507

Merged
HuiJun merged 2 commits into
developfrom
test/state-action-default-performances
Oct 25, 2026
Merged

HuiJun merged 2 commits into
developfrom
test/state-action-default-performances

Conversation

@devin-ai-integration

@devin-ai-integration devin-ai-integration Bot commented Oct 25, 2026 •

Copy link
Copy Markdown
Contributor

What and why

A state declaring no do or exit action still reads one performance under sm.doAction and sm.exitAction (->size() 1, ->isEmpty() false), beside its declared entry action en under sm.entryAction. That is the library's reading, and this PR pins it rather than changing it: States.sysml declares StateAction's three actions with no multiplicity of their own —

entry action entryAction :>> 'entry';
do action doAction: Action :>> 'do';
exit action exitAction: Action :>> 'exit';

— so each inherits the [1] of the StatePerformance step it redefines (StatePerformances.kerml: step entry[1]; step do[1] subsets middle; step exit[1];, identical in the pilot's library XMI). An undeclared one is therefore the default performance the runtime materializes for any [1] composite feature (runtime/shape.go inheritedMultiplicity, runtime/instance.go materializeComposite), not an empty value. The [0..1] on StateDefinition::doAction : ActionUsage [0..1] is the metamodel's bound on the do declarations a state may own (SysML v2 §8.3.17), not the multiplicity of the performance; the pilot evaluator answering sm.doAction as an empty sequence reads that declaration, not an instance.

The library's genuinely optional behavior-side features already hold nothing when unset, and the fixture pins those beside the state actions: StatePerformance::incomingTransitionTrigger : MessageTransfer[0..1] and accepted : Transfer[0..1] read null (->size() 0), View::viewRendering : Rendering[0..1] reads [].

No runtime code changes. Readings on develop (111a59a) and on this branch are the same:

probe develop branch
sm.entryAction, sm.doAction, sm.exitAction beside entry action en one object each same
sm.doAction->size() / ->isEmpty() 1 / false same
sm.entryAction->size() 1 same
sm.doAction->size() beside a declared do action run 1 same
sm.incomingTransitionTrigger, sm.accepted null, ->size() 0 same
v.viewRendering [], ->size() 0 same
OccurrencesTest::p1.v, new OccurrencesTest::P1().v 2, 2 same

No golden, baseline or sweep row moves (TestLibraryAndPrefixSweep already records st.doAction, es.doAction and S1().doAction as object:Actions::Action).

Not in this PR:

  • the identity of sm.entryAction with the declared en (sm.entryAction == sm.en is false on develop; SysML v2 checkActionUsageStateActionRedefinition makes en redefine entryAction), which fix(runtime): derive implicit specializations for every performance the run creates #1492 establishes through its state-action role redefinitions — the fixture pins counts and presence only, so it holds on both sides of that change.
  • a state def's attribute bound over its own occurrence features (attribute n : Integer = entryAction->SequenceFunctions::size();, likewise en->size()) evaluates in the live machine but is not re-derived in a held-image copy (StateDataWithError: no value for feature entryAction; the copy's state data reads {}) — a gap in the held image's restore of state binding cells on develop, which is why the fixture reads the counts from the part.

Specification basis

KerML 1.0 §9.2.11.1 State Performances Overview ("entry [1] … do [1]: a middle Performance that starts before the others … exit [1]"); Kernel Semantic Library/StatePerformances.kerml; Systems Library/States.sysml StateAction; SysML v2 §8.3.17 StateDefinition::doAction : ActionUsage [0..1] (declaration count, not instance multiplicity). New row in docs/project/spec-compliance.md under State Machine, after the exit-actions row.

How it was verified

  • conformance state_action_default_performances: a state with a declared entry only (entryAction/doAction/exitAction present, counts 1/1/1, doIsEmpty false, incomingTransitionTrigger and accepted null with counts 0), a state with declared do/exit (counts 1/1), a view's viewRendering []; the counts are read through the exhibit usage from the owning part; flipping m.doCount to 0 fails the case (value = 1, want 0); TestHeldImageRoundTrip carries the case
  • go build ./..., go vet ./..., gofmt -l . empty, make lint, go test ./internal/exec/runtime/..., go test ./cmd/sysml/..., go test ./... with the training, pilot, spec-example and pilot-library-XMI corpora downloaded and their OPENSYSML_REQUIRE_* set, python3 scripts/changelog.py check, python3 scripts/check-doc-ids.py
  • dry-merged against the heads of fix(runtime): derive implicit specializations for every performance the run creates #1492 and fix(parser,runtime): satisfy by takes a feature chain; a satisfy stating no by reads its owner as the subject #1466: no conflicts

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

Link to Devin session: https://nasa-jpl-demo.devinenterprise.com/sessions/aa6cec59dbcc4d458aa99224cfb6490f
Open in Devin Desktop: https://nasa-jpl-demo.devinenterprise.com/desktop/session/aa6cec59dbcc4d458aa99224cfb6490f?variant=devin
Requested by: @HuiJun

…mance each

States::StateAction redefines StatePerformance's entry[1], do[1] and exit[1]
steps without a multiplicity of its own, so an undeclared do or exit action
is the default performance of a [1] composite feature, not an empty value;
the library's [0..1] behavior-side features (incomingTransitionTrigger,
accepted, viewRendering) hold nothing when unset.

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

Copy link
Copy Markdown
Contributor Author

I'll fix CI failures and address comments from users with write access. I'll skip comments containing "(aside)".

  • Disable automatic comment, CI, and merge conflict monitoring

…g part

A state's attribute bound over its own occurrence features (`entryAction->size()`)
is not re-derived in a held-image copy, so the fixture reads the counts through
the exhibit usage from the owning part, which the image carries.

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

Copy link
Copy Markdown
Contributor Author

b6978b3 moves the fixture's count attributes from the state defs to the exhibiting part (entered.doAction->size() on Machine, sheet.viewRendering->size() on Rig). The first form failed TestHeldImageRoundTrip: a state def's attribute bound over its own occurrence features (attribute n : Integer = entryAction->size(), likewise en->size()) evaluates in the live machine but is not re-derived in a held-image copy (no value for feature entryAction, so the copy's state data reads {} where the source reads the counts). That is a gap in the held image's restore of state binding cells, present on develop and independent of this PR, so the fixture reads the same counts from the part, which the image carries; the pinned readings are unchanged (1/1/1, isEmpty false, 0/0, []).

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 1 potential issue.

Devin Review

@HuiJun
HuiJun merged commit 1f8ff30 into develop Oct 25, 2026
53 checks passed
@HuiJun
HuiJun deleted the test/state-action-default-performances branch October 25, 2026 16:47
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