Skip to content

engine: choice pseudostate resolution + validation (SPEC §5.5.1)#35

Merged
fruwe merged 1 commit into
mainfrom
choice-impl
Jul 1, 2026
Merged

engine: choice pseudostate resolution + validation (SPEC §5.5.1)#35
fruwe merged 1 commit into
mainfrom
choice-impl

Conversation

@fruwe

@fruwe fruwe commented Jul 1, 2026

Copy link
Copy Markdown
Member

Closes #34. Implements the choice pseudostate (spec: fruwehq/harel#30; cases: fruwehq/harel-conformance#8).

What

  • Model: a node with a choice branch list is a transient pseudostate (type=choice), never in the active configuration.
  • Dispatch (run_transition): when a target resolves to a choice, the triggering action runs, then the branch chain is resolved in the source scope (first passing guard, or the mandatory else; branch action runs; chained choices repeat) to a real target, which is then entered as an ordinary external transition. Branch guards see esvs just assigned by the trigger — the dynamic behavior guarded lists can't do.
  • Validation: exactly one default (else) branch, and it must be last (collect_errors → load-time); branch targets resolve and the choice graph is acyclic (Machine build).
  • Bundles the updated schema, bumps to 0.0.2 (so the conformance fetch picks up cases 23–25 on main).

Verify

  • Unit: tests/test_choice.py — dynamic branch, else, chained (parametrized), and four validation rejections (no else / else-not-last / cyclic / unresolved target). 129 unit tests, ruff + mypy clean.
  • Conformance: 57 pass incl. 23-choice, 24-choice-chain, 25-choice-invalid (run locally against harel#30 + conformance#8; CI fetches main since v0.0.2 isn't tagged yet).

Note: this is 0.0.2 material (spec changed). Cut v0.0.2 on harel + harel-conformance when ready to snapshot.

Recognize choice nodes (a 'choice' branch list) as transient pseudostates,
excluded from the active configuration. In run_transition, when a target resolves
to a choice, run the triggering action, then resolve the branch chain in the
source scope (first passing guard or the mandatory else; branch action runs;
chained choices repeat) to a real target, then exit/enter as an external
transition. Validate: exactly one else and last (collect_errors); branch targets
resolve and the choice graph is acyclic (Machine build). Bundle the updated schema,
bump to 0.0.2, add cases 23-25 to the harness, and add unit tests.

Closes #34.
@fruwe fruwe merged commit db52d79 into main Jul 1, 2026
2 checks passed
@fruwe fruwe deleted the choice-impl branch July 1, 2026 11: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.

engine: choice pseudostate resolution + validation

1 participant