Skip to content

Require statically inspectable machine transitions - #125

Merged
SandroMaglione merged 1 commit into
mainfrom
codex/static-transition-plans
Aug 17, 2026
Merged

Require statically inspectable machine transitions#125
SandroMaglione merged 1 commit into
mainfrom
codex/static-transition-plans

Conversation

@SandroMaglione

Copy link
Copy Markdown
Member

Summary

  • require every event, lifecycle, choice, and invocation transition to use Machine.transition, with a statically selected target and a separately inferred resolver
  • add titled Option-based conditional branches with an explicit otherwise, and expose exact branch targets through transition topology for complete visualization
  • move initial construction to the same target / resolve shape, remove DefinedStates.initial, and rename reusable process construction from Machine.transition to Machine.logic
  • migrate documentation, tests, consumers, performance fixtures, and all examples to the new API

Changeset

  • Added or updated for a library or package-metadata change
  • Not required because this PR does not change src/ or package.json

Validation

  • pnpm check
  • Relevant example checks, when examples changed
  • Automated type-performance measurement passed or was not required
  • Automated runtime- and memory-performance measurement passed or was not required

@github-actions

github-actions Bot commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

Type performance

Measured with TypeScript 6.0.3 and skipLibCheck=true.

Scenario Base PR Difference
Effect only 55 55 0 (0.0%)
Import effect-machine 55 55 0 (0.0%)
Machine.defineStates (3 states) 3,039 3,039 0 (0.0%)
Machine.make (3 states, 2 events) 13,199 10,439 -2,760 (-20.9%)
machine.handle (3 states, 2 transitions) 30,492 53,523 +23,031 (+75.5%)
Machine.invoke (state-dependent Effect) 30,762 57,503 +26,741 (+86.9%)
machine.handle (depth 24) 190,320 188,289 -2,031 (-1.1%)
machine.handle (wide depth 16) 222,536 219,355 -3,181 (-1.4%)
machine.handle (parallel/history/choice) 129,927 132,402 +2,475 (+1.9%)
machine.handle (4 successive calls) 137,396 138,079 +683 (+0.5%)
machine exact input/output/error/services 111,673 115,149 +3,476 (+3.1%)
execution adapter readiness 122,677 124,980 +2,303 (+1.9%)

Marginal instantiations are measured against the matching setup without that API call:

Scenario Base PR Difference
Import effect-machine 0 0 0
Machine.defineStates (3 states) 2,984 2,984 0 (0.0%)
Machine.make (3 states, 2 events) 10,152 7,392 -2,760 (-27.2%)
machine.handle (3 states, 2 transitions) 17,293 43,084 +25,791 (+149.1%)
Machine.invoke (state-dependent Effect) 19,729 48,657 +28,928 (+146.6%)
machine.handle (depth 24) 170,251 168,599 -1,652 (-1.0%)
machine.handle (wide depth 16) 203,528 200,664 -2,864 (-1.4%)
machine.handle (parallel/history/choice) 104,273 112,726 +8,453 (+8.1%)
machine.handle (4 successive calls) 116,145 122,533 +6,388 (+5.5%)
machine exact input/output/error/services 95,142 101,058 +5,916 (+6.2%)
execution adapter readiness 87,561 62,726 -24,835 (-28.4%)
Check times (informational)
Scenario Base PR
Effect only 0.03s 0.03s
Import effect-machine 0.03s 0.03s
Machine.defineStates (3 states) 0.10s 0.10s
Machine.make (3 states, 2 events) 0.20s 0.17s
machine.handle (3 states, 2 transitions) 0.27s 0.34s
Machine.invoke (state-dependent Effect) 0.32s 0.40s
machine.handle (depth 24) 0.73s 0.77s
machine.handle (wide depth 16) 0.76s 0.79s
machine.handle (parallel/history/choice) 0.60s 0.63s
machine.handle (4 successive calls) 0.60s 0.62s
machine exact input/output/error/services 0.54s 0.58s
execution adapter readiness 0.55s 0.56s

Type instantiations are the comparison metric. Check time varies with runner load and is informational only.

@SandroMaglione
SandroMaglione force-pushed the codex/static-transition-plans branch from 25d9427 to 9324c20 Compare August 17, 2026 06:21
@github-actions

Copy link
Copy Markdown
Contributor

Runtime performance

Median of 5 independent benchmark processes on AMD EPYC 7763 64-Core Processor with Node v24.19.0.

Pull request baseline

Scenario Effect Machine
Plan counter transitions 115,214 transitions/s
Drain burst with terminal fence 343,333 increments/s
Drain burst with a change observer 322,746 increments/s
Lookup and send to one child 286,078 increments/s
Start and stop a machine 139,606 machines/s
Start and stop a parent with one child 28,722 families/s
Plan transitions through a compound state 99,095 transitions/s
Plan transitions through parallel regions 81,276 transitions/s
Drain burst through a compound state 297,245 events/s
Drain burst through two parallel regions 297,419 events/s
Drain a compound-state burst with a change observer 282,473 events/s

Process runtime reference points

Scenario Effect Machine
Start and stop a raw generic process 14,759 processes/s
Start and stop a raw compiled process 60,824 processes/s
Memory profile Effect Machine
Idle machine 1.8 KiB
Raw generic managed process 13.9 KiB
Raw compiled process 3.1 KiB
Two independent idle machines 3.4 KiB
Idle parent with one child 5.5 KiB
Parent with observed child registry 9.7 KiB
Parent with observed invoked child snapshots 6.1 KiB

Effect Machine change from base

Metric Base Base variability PR PR variability Difference
Plan counter transitions 119,218 transitions/s 2.5% MAD 115,214 transitions/s 1.0% MAD -3.4%
Drain burst with terminal fence 376,804 increments/s 0.3% MAD 343,333 increments/s 1.1% MAD -8.9%
Drain burst with a change observer 351,789 increments/s 0.9% MAD 322,746 increments/s 1.3% MAD -8.3%
Lookup and send to one child 309,707 increments/s 1.0% MAD 286,078 increments/s 1.7% MAD -7.6%
Start and stop a machine 150,083 machines/s 0.8% MAD 139,606 machines/s 2.1% MAD -7.0%
Start and stop a parent with one child 30,054 families/s 0.4% MAD 28,722 families/s 1.9% MAD -4.4%
Plan transitions through a compound state 106,343 transitions/s 1.3% MAD 99,095 transitions/s 0.8% MAD -6.8%
Plan transitions through parallel regions 84,703 transitions/s 1.8% MAD 81,276 transitions/s 1.1% MAD -4.0%
Drain burst through a compound state 338,310 events/s 0.7% MAD 297,245 events/s 1.0% MAD -12.1%
Drain burst through two parallel regions 317,058 events/s 2.6% MAD 297,419 events/s 1.3% MAD -6.2%
Drain a compound-state burst with a change observer 317,546 events/s 1.4% MAD 282,473 events/s 1.5% MAD -11.0%
Idle machine heap per unit 1.8 KiB 0.0% MAD 1.8 KiB 0.0% MAD +1.0%
Raw generic managed process heap per unit 13.9 KiB 0.0% MAD 13.9 KiB 0.0% MAD +0.0%
Raw compiled process heap per unit 3.1 KiB 0.4% MAD 3.1 KiB 0.1% MAD -0.3%
Two independent idle machines heap per unit 3.4 KiB 0.0% MAD 3.4 KiB 0.1% MAD -0.7%
Idle parent with one child heap per unit 5.5 KiB 0.0% MAD 5.5 KiB 0.0% MAD +0.2%
Parent with observed child registry heap per unit 9.7 KiB 0.0% MAD 9.7 KiB 0.0% MAD +0.1%
Parent with observed invoked child snapshots heap per unit 6.0 KiB 0.0% MAD 6.1 KiB 0.1% MAD +0.3%

Process runtime reference change from base

Metric Base Base variability PR PR variability Difference
Start and stop a raw generic process 15,540 processes/s 2.3% MAD 14,759 processes/s 1.1% MAD -5.0%
Start and stop a raw compiled process 61,421 processes/s 0.7% MAD 60,824 processes/s 0.7% MAD -1.0%

Regression guard

No large, noise-adjusted throughput or heap regressions detected.

Versions and interpretation
  • Effect Machine: 0.13.0

Higher throughput is better; lower heap is better. Variability is the median absolute deviation across independent processes, relative to their median. Small differences on shared GitHub-hosted hardware remain informational; the required guard rejects only large changes beyond the measured noise allowance.

@SandroMaglione
SandroMaglione merged commit 2c67924 into main Aug 17, 2026
13 checks passed
@SandroMaglione
SandroMaglione deleted the codex/static-transition-plans branch August 17, 2026 06:27
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