Skip to content

Add required and optional parent protocols - #147

Merged
SandroMaglione merged 1 commit into
mainfrom
codex/required-optional-parent
Aug 19, 2026
Merged

Add required and optional parent protocols#147
SandroMaglione merged 1 commit into
mainfrom
codex/required-optional-parent

Conversation

@SandroMaglione

Copy link
Copy Markdown
Member

Summary

  • replace parentEvents with explicit Machine.parent and Machine.optionalParent declarations
  • make required parent targets non-optional and reject child-only machines from every independent root API
  • omit undeclared parent references from behavior contexts while preserving scoped child runtime delivery
  • migrate documentation, examples, consumer fixtures, and add generic-versus-compiled regression coverage

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

Local validation also included pnpm check in examples/pokemon, pnpm perf:types, and pnpm perf:runtime.

@github-actions

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.states (3 states) 3,039 3,039 0 (0.0%)
Machine.make (3 states, 2 events) 10,761 10,759 -2 (-0.0%)
machine.handle (3 states, 2 transitions) 29,177 29,625 +448 (+1.5%)
fluent transition (10 named branches) 109,470 107,405 -2,065 (-1.9%)
Machine.invoke (state-dependent Effect) 92,024 92,583 +559 (+0.6%)
machine.handle (depth 24) 198,478 196,139 -2,339 (-1.2%)
machine.handle (wide depth 16) 229,624 227,285 -2,339 (-1.0%)
machine.handle (parallel/history/choice) 133,024 130,795 -2,229 (-1.7%)
machine definition (3 independent implementations) 132,018 129,848 -2,170 (-1.6%)
machine exact input/output/error/services 117,186 114,991 -2,195 (-1.9%)
execution adapter readiness 126,635 124,898 -1,737 (-1.4%)

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

Scenario Base PR Difference
Import effect-machine 0 0 0
Machine.states (3 states) 2,984 2,984 0 (0.0%)
Machine.make (3 states, 2 events) 7,714 7,712 -2 (-0.0%)
machine.handle (3 states, 2 transitions) 18,416 18,866 +450 (+2.4%)
fluent transition (10 named branches) 99,219 97,156 -2,063 (-2.1%)
Machine.invoke (state-dependent Effect) 82,757 83,318 +561 (+0.7%)
machine.handle (depth 24) 177,780 175,443 -2,337 (-1.3%)
machine.handle (wide depth 16) 210,133 207,796 -2,337 (-1.1%)
machine.handle (parallel/history/choice) 112,757 110,532 -2,225 (-2.0%)
machine definition (3 independent implementations) 116,045 113,879 -2,166 (-1.9%)
machine exact input/output/error/services 102,673 100,480 -2,193 (-2.1%)
execution adapter readiness 95,462 93,457 -2,005 (-2.1%)
Check times (informational)
Scenario Base PR
Effect only 0.03s 0.03s
Import effect-machine 0.03s 0.03s
Machine.states (3 states) 0.11s 0.11s
Machine.make (3 states, 2 events) 0.17s 0.18s
machine.handle (3 states, 2 transitions) 0.26s 0.28s
fluent transition (10 named branches) 0.53s 0.51s
Machine.invoke (state-dependent Effect) 0.48s 0.50s
machine.handle (depth 24) 0.82s 0.84s
machine.handle (wide depth 16) 0.84s 0.84s
machine.handle (parallel/history/choice) 0.67s 0.65s
machine definition (3 independent implementations) 0.66s 0.66s
machine exact input/output/error/services 0.62s 0.64s
execution adapter readiness 0.62s 0.61s

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

@github-actions

Copy link
Copy Markdown
Contributor

Runtime performance

Median of 5 independent benchmark processes on AMD EPYC 9V74 80-Core Processor with Node v24.19.0.

Pull request baseline

Scenario Effect Machine
Plan counter transitions 117,312 transitions/s
Drain burst with terminal fence 347,183 increments/s
Drain burst with a change observer 325,889 increments/s
Lookup and send to one child 296,502 increments/s
Start and stop a machine 144,300 machines/s
Start and stop a parent with one child 41,244 families/s
Plan transitions through a compound state 102,548 transitions/s
Plan transitions through parallel regions 85,296 transitions/s
Drain burst through a compound state 283,619 events/s
Drain burst through two parallel regions 284,229 events/s
Drain a compound-state burst with a change observer 267,284 events/s

Process runtime reference points

Scenario Effect Machine
Start and stop a raw generic process 26,269 processes/s
Start and stop a raw compiled process 67,650 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.8 KiB
Parent with observed child registry 10.0 KiB
Parent with observed invoked child snapshots 6.3 KiB

Effect Machine change from base

Metric Base Base variability PR PR variability Difference
Plan counter transitions 117,252 transitions/s 1.4% MAD 117,312 transitions/s 0.8% MAD +0.1%
Drain burst with terminal fence 345,167 increments/s 0.8% MAD 347,183 increments/s 0.6% MAD +0.6%
Drain burst with a change observer 324,972 increments/s 1.9% MAD 325,889 increments/s 0.5% MAD +0.3%
Lookup and send to one child 295,666 increments/s 1.3% MAD 296,502 increments/s 0.4% MAD +0.3%
Start and stop a machine 143,678 machines/s 0.4% MAD 144,300 machines/s 0.7% MAD +0.4%
Start and stop a parent with one child 41,901 families/s 1.5% MAD 41,244 families/s 1.1% MAD -1.6%
Plan transitions through a compound state 102,240 transitions/s 2.2% MAD 102,548 transitions/s 0.8% MAD +0.3%
Plan transitions through parallel regions 84,414 transitions/s 2.5% MAD 85,296 transitions/s 0.2% MAD +1.0%
Drain burst through a compound state 284,891 events/s 0.3% MAD 283,619 events/s 0.8% MAD -0.4%
Drain burst through two parallel regions 291,314 events/s 1.5% MAD 284,229 events/s 1.9% MAD -2.4%
Drain a compound-state burst with a change observer 270,631 events/s 0.6% MAD 267,284 events/s 0.6% MAD -1.2%
Idle machine heap per unit 1.8 KiB 0.3% MAD 1.8 KiB 0.1% MAD -0.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.1% MAD 3.1 KiB 0.0% MAD -0.4%
Two independent idle machines heap per unit 3.4 KiB 0.1% MAD 3.4 KiB 0.1% MAD +0.0%
Idle parent with one child heap per unit 5.8 KiB 0.0% MAD 5.8 KiB 0.0% MAD +0.0%
Parent with observed child registry heap per unit 10.0 KiB 0.0% MAD 10.0 KiB 0.0% MAD +0.0%
Parent with observed invoked child snapshots heap per unit 6.3 KiB 0.0% MAD 6.3 KiB 0.0% MAD -0.0%

Process runtime reference change from base

Metric Base Base variability PR PR variability Difference
Start and stop a raw generic process 26,727 processes/s 2.8% MAD 26,269 processes/s 1.4% MAD -1.7%
Start and stop a raw compiled process 68,861 processes/s 0.4% MAD 67,650 processes/s 1.1% MAD -1.8%

Regression guard

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

Versions and interpretation
  • Effect Machine: 0.16.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 600149b into main Aug 19, 2026
13 checks passed
@SandroMaglione
SandroMaglione deleted the codex/required-optional-parent branch August 19, 2026 10:41
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