Skip to content

Fix machine boundary validation and implementation ownership - #205

Merged
SandroMaglione merged 1 commit into
mainfrom
codex/implementation-quality
Sep 6, 2026
Merged

Fix machine boundary validation and implementation ownership#205
SandroMaglione merged 1 commit into
mainfrom
codex/implementation-quality

Conversation

@SandroMaglione

@SandroMaglione SandroMaglione commented Sep 6, 2026

Copy link
Copy Markdown
Member

Summary

  • Keep Machine.can behavior and fix its types to accept internal events. MachineRef.send still accepts only public events; the JSDoc example is compiled in CI.
  • Preserve interruption during snapshot serialization, revalidate reused event and emission values, and capture machine definitions so later caller mutations cannot change their behavior.
  • Make MachineTest.verify lazy and compare decoded values without losing information through JSON. Extract target builders, child bookkeeping, invocation definitions, and shared requirement types into focused internal modules.
  • Serialize devtools refreshes, stop watcher work with its server scope, and prevent lint diagnostics for shadowed machine bindings. Add regression tests and strengthen generic-versus-optimized comparisons.

Changeset

  • Added or updated for a library or package-metadata change
  • Not required because this PR does not change a publishable package

Compatible fixes and implementation improvements use a patch changeset.

Validation

  • pnpm check
  • Automated type-performance measurement passed or was not required
  • Automated runtime- and memory-performance measurement passed or was not required

Local pnpm perf:types and pnpm perf:runtime passed. Hosted CI, type performance, and runtime performance passed, and both comparison artifacts were inspected. Type scenarios added at most four instantiations. Across five independent processes per version, throughput changes ranged from -0.8% to +1.9%, heap usage remained essentially unchanged, and the regression guard passed.

@github-actions

github-actions Bot commented Sep 6, 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.states (3 states) 3,039 3,039 0 (0.0%)
Machine.make (3 states, 2 events) 10,787 10,787 0 (0.0%)
machine.handle (3 states, 2 transitions) 28,551 28,551 0 (0.0%)
fluent transition (10 named branches) 122,775 122,777 +2 (+0.0%)
fluent invocation (state-dependent Effect) 108,429 108,429 0 (0.0%)
machine.handle (depth 24) 207,970 207,972 +2 (+0.0%)
machine.handle (wide depth 16) 236,332 236,334 +2 (+0.0%)
machine.handle (parallel/history/choice) 144,812 144,814 +2 (+0.0%)
machine definition (3 independent implementations) 143,617 143,619 +2 (+0.0%)
machine exact input/output/error/services 129,873 129,877 +4 (+0.0%)
execution adapter readiness 136,469 136,468 -1 (-0.0%)

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,740 7,740 0 (0.0%)
machine.handle (3 states, 2 transitions) 17,764 17,764 0 (0.0%)
fluent transition (10 named branches) 112,498 112,500 +2 (+0.0%)
fluent invocation (state-dependent Effect) 99,018 99,018 0 (0.0%)
machine.handle (depth 24) 187,474 187,476 +2 (+0.0%)
machine.handle (wide depth 16) 217,043 217,045 +2 (+0.0%)
machine.handle (parallel/history/choice) 124,167 124,169 +2 (+0.0%)
machine definition (3 independent implementations) 127,576 127,578 +2 (+0.0%)
machine exact input/output/error/services 115,217 115,221 +4 (+0.0%)
execution adapter readiness 106,299 106,298 -1 (-0.0%)
Check times (informational)
Scenario Base PR
Effect only 0.02s 0.02s
Import effect-machine 0.02s 0.02s
Machine.states (3 states) 0.07s 0.07s
Machine.make (3 states, 2 events) 0.12s 0.12s
machine.handle (3 states, 2 transitions) 0.19s 0.19s
fluent transition (10 named branches) 0.41s 0.42s
fluent invocation (state-dependent Effect) 0.41s 0.42s
machine.handle (depth 24) 0.61s 0.62s
machine.handle (wide depth 16) 0.63s 0.63s
machine.handle (parallel/history/choice) 0.50s 0.50s
machine definition (3 independent implementations) 0.52s 0.52s
machine exact input/output/error/services 0.47s 0.48s
execution adapter readiness 0.48s 0.47s

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

@github-actions

github-actions Bot commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

Runtime performance

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

Pull request baseline

Scenario Effect Machine
Plan counter transitions 121,970 transitions/s
Drain burst with terminal fence 391,577 increments/s
Drain burst with a change observer 364,206 increments/s
Lookup and send to one child 319,279 increments/s
Start and stop a machine 143,390 machines/s
Start and stop a parent with one child 28,965 families/s
Plan transitions through a compound state 105,098 transitions/s
Plan transitions through parallel regions 86,785 transitions/s
Drain burst through a compound state 309,812 events/s
Drain burst through two parallel regions 306,028 events/s
Drain a compound-state burst with a change observer 296,104 events/s

Process runtime reference points

Scenario Effect Machine
Start and stop a raw generic process 14,969 processes/s
Start and stop a raw compiled process 62,073 processes/s
Memory profile Effect Machine
Idle machine 1.7 KiB
Raw generic managed process 13.9 KiB
Raw compiled process 3.2 KiB
Two independent idle machines 3.4 KiB
Idle parent with one child 5.8 KiB
Parent with observed child registry 9.8 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 121,257 transitions/s 0.8% MAD 121,970 transitions/s 2.4% MAD +0.6%
Drain burst with terminal fence 388,619 increments/s 1.0% MAD 391,577 increments/s 0.5% MAD +0.8%
Drain burst with a change observer 360,143 increments/s 0.2% MAD 364,206 increments/s 0.4% MAD +1.1%
Lookup and send to one child 316,495 increments/s 0.5% MAD 319,279 increments/s 0.5% MAD +0.9%
Start and stop a machine 143,823 machines/s 1.1% MAD 143,390 machines/s 1.0% MAD -0.3%
Start and stop a parent with one child 28,873 families/s 2.0% MAD 28,965 families/s 0.7% MAD +0.3%
Plan transitions through a compound state 105,826 transitions/s 1.5% MAD 105,098 transitions/s 2.1% MAD -0.7%
Plan transitions through parallel regions 87,457 transitions/s 0.7% MAD 86,785 transitions/s 0.2% MAD -0.8%
Drain burst through a compound state 304,448 events/s 2.6% MAD 309,812 events/s 2.1% MAD +1.8%
Drain burst through two parallel regions 301,802 events/s 1.6% MAD 306,028 events/s 2.0% MAD +1.4%
Drain a compound-state burst with a change observer 290,559 events/s 1.6% MAD 296,104 events/s 2.0% MAD +1.9%
Idle machine heap per unit 1.8 KiB 0.2% MAD 1.7 KiB 0.0% MAD -0.3%
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.2 KiB 0.3% MAD 3.2 KiB 0.1% MAD +0.6%
Two independent idle machines heap per unit 3.4 KiB 0.1% MAD 3.4 KiB 0.0% MAD +0.0%
Idle parent with one child heap per unit 5.8 KiB 0.1% MAD 5.8 KiB 0.0% MAD +0.0%
Parent with observed child registry heap per unit 9.8 KiB 0.0% MAD 9.8 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.1% MAD -0.4%

Process runtime reference change from base

Metric Base Base variability PR PR variability Difference
Start and stop a raw generic process 14,994 processes/s 1.4% MAD 14,969 processes/s 1.1% MAD -0.2%
Start and stop a raw compiled process 61,763 processes/s 2.2% MAD 62,073 processes/s 2.4% MAD +0.5%

Regression guard

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

Versions and interpretation
  • Effect Machine: 0.31.2

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 163be91 into main Sep 6, 2026
8 checks passed
@SandroMaglione
SandroMaglione deleted the codex/implementation-quality branch September 6, 2026 09:59
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