Skip to content

fix(runtime): read an action's results under the run it moved in - #1879

Merged
HuiJun merged 1 commit into
developfrom
fix/advance-order-dependent-annotation
Nov 3, 2026
Merged

HuiJun merged 1 commit into
developfrom
fix/advance-order-dependent-annotation

Conversation

@devin-ai-integration

@devin-ai-integration devin-ai-integration Bot commented Nov 3, 2026 •

Copy link
Copy Markdown
Contributor

What and why

Bug. sysml examples/analysis-demo/lander.sysml -instantiate Landers::scout -action Timing::groundWatch -advance 5 prints sawBraking = [false] bare, although the run's summary says 1 choice point and the same command on v0.11.0 (and the default run without -advance on develop) prints sawBraking = [false] (order-dependent; 1 choice point — explore shows the set). Found by the 0.12.0 release docs audit.

Bisected cause. git bisect v0.11.0..develop with that reproducer names c8e6c9d (#1619, fix(runtime): mark order dependence on chained places and same-step sibling reads). That commit made ActionExecutor.ResultsWithError enter the executor's own run state (e.driven.state) before deriving the results, so a derivation would not install a fresh run and drop the marks of the run just ended. Under -advance, though, the behaviors started do not move in their own run states: Context.AdvanceUntil runs them nested under the clock's run (ctx.clockRun), which is where the due-order choice point (ChoiceDueOrder) and its marks are recorded, while each executor's own state stays idle (no notes, no marks). Entering that idle state installed it over the clock's run, so namedValue → Context.OrderDependent read it afterwards and found no choice point: the marker vanished only on the -advance path (default runs and -schedule explore move in the executor's own run, where state and clock coincide).

Fix. executorRun now records the run its latest call moved the executor in (under: its own state, or the run installed over it when the call was nested, as the clock's advance nests it); beginExecutorRun sets it and ResultsWithError reads under that run instead of the idle one. Snapshots (actionCapture/stateCapture) and held images (imagedAction/imagedState) carry it beside the run state so a restore keeps the pair consistent. Nothing prints the marker unconditionally and no output is patched: OrderDependent simply reads the run that holds the marks.

Specification basis

No new clause; this restores the surface described by the existing row of docs/project/spec-compliance.md ("A default run reports its values only up to the partial order the library fixes…", KerML 1.1 §9.2.4 Occurrences, §9.2.6 Performances): a value a conflicting alternative wrote prints with the marker on every surface. The row's implementation note for ResultsWithError and its test list are updated; the row's status does not move. docs/internals/design/scheduling.md describes the same read and is updated.

How it was verified

  • New cmd/sysml/run_test.go:TestAdvanceMarksOrderDependentResults (red on develop, green here) asserts the marker on -advance 5 over the existing dueTogetherModel (an action and a state transition due at one instant), beside the explore test of the same fixture.

  • Reproducer on the lander example:

    v0.11.0 (git worktree at the tag):

    ✓ Advanced to 5.0 (1 event(s) processed)
      Action state: Completed
      Tokens: 0
      1 choice point; %trace on to see them
      Action steps taken: 5
    ✓ Action completed
      Results:
        armed = [true]
        sawBraking = [false] (order-dependent; 1 choice point — explore shows the set)
      standing: value (observed: 1 run under reverse)
    

    develop (1dc7d36):

    ✓ Advanced to 5.0 (1 event(s) processed)
      Action state: Completed
      Tokens: 0
      1 choice point; %trace on to see them
      Action steps taken: 5
    ✓ Action completed
      Results:
        armed = [true]
        sawBraking = [false]
      standing: value (observed: 1 run under reverse)
    

    this branch:

    ✓ Advanced to 5.0 (1 event(s) processed)
      Action state: Completed
      Tokens: 0
      1 choice point; %trace on to see them
      Action steps taken: 5
    ✓ Action completed
      Results:
        armed = [true]
        sawBraking = [false] (order-dependent; 1 choice point — explore shows the set)
      standing: value (observed: 1 run under reverse)
    
  • Gates (local):

    gofmt -l .                      → (empty)
    

go build ./... → ok
go vet ./... → ok
make lint → ✓ Lint passed (staticcheck + gosec)
python3 scripts/changelog.py check → ok
go test ./internal/exec/runtime/... ./internal/frontend/repl/... ./cmd/sysml/... → ok
go test ./... -timeout 40m → ok (every package; exit 0)


## Checklist

- [x] `make test` and `make lint` pass locally
- [x] Tests added or updated for the change
- [x] Documentation extended where it already covers the surface (see CONTRIBUTING.md)
- [x] Changelog entry added as `changes/unreleased/<slug>.<section>.md`, not as an edit to `CHANGELOG.md`
- [x] baselines regenerated and `make docs-counts` run if a gate count moved (compliance rows need nothing: the census is counted at docs build)
- [x] 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/6f396323532544c89a4a6fab04ef391e
Open in Devin Desktop: https://nasa-jpl-demo.devinenterprise.com/desktop/session/6f396323532544c89a4a6fab04ef391e?variant=devin
Requested by: @HuiJun

Under -advance the behaviors started move in the clock's run, where the
due-order choice point and its marks are recorded, while each executor's
own run state stays idle. ResultsWithError entered that idle run to derive
the results, so the surface reading the marks afterwards found none and a
result standing on the choice point printed bare, without the
(order-dependent; 1 choice point — explore shows the set) marker the
default run prints.

executorRun now records the run its latest call moved the executor in
(under: its own state, or the run installed over it when the call was
nested, as the clock's advance nests it), beginExecutorRun sets it, and
ResultsWithError reads under that run; snapshots and held images carry it
with the run state. A CLI test asserts the marker on an -advance run of
an action and a state machine due at one instant.

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

@devin-ai-integration
devin-ai-integration Bot marked this pull request as ready for review November 3, 2026 04:38

@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: No Issues Found

Devin Review analyzed this PR and found no bugs or issues to report.

Devin Review

@HuiJun
HuiJun merged commit 5487b4d into develop Nov 3, 2026
33 of 54 checks passed
@HuiJun
HuiJun deleted the fix/advance-order-dependent-annotation branch November 3, 2026 08:00
devin-ai-integration Bot added a commit that referenced this pull request Nov 3, 2026
Brings #1871, #1873, #1874, #1876, #1877, #1878, #1879, #1880, #1881, #1882 and #1883 into 0.12.0; the eleven changelog fragments are folded into the 0.12.0 section.

Co-Authored-By: jason.han <hanhuijun@gmail.com>
@devin-ai-integration devin-ai-integration Bot mentioned this pull request Nov 3, 2026
4 of 6 tasks
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