Skip to content

Add combined retained owner updates - #166

Merged
SandroMaglione merged 1 commit into
mainfrom
codex/combined-state-updates
Aug 23, 2026
Merged

Add combined retained owner updates#166
SandroMaglione merged 1 commit into
mainfrom
codex/combined-state-updates

Conversation

@SandroMaglione

@SandroMaglione SandroMaglione commented Aug 23, 2026

Copy link
Copy Markdown
Member

Summary

  • make state construction modes explicit with .from(...) for schema make input and .decoded(...) for already-decoded values, removing callable valued builders
  • add .updating(ownerSelector) so one retained valued ancestor can be replaced atomically with a local or branch topology change; the resolver must call destination .update(...) at compile time
  • align generic and indexed planning, conflict handling, inspection, visualization, verification, persistence-compatible snapshots, tests, benchmarks, consumer fixtures, and documentation with the combined instruction

Changeset

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

Adds a minor changeset because this is a breaking pre-1.0 public API change.

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 also passed.

@github-actions

github-actions Bot commented Aug 23, 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,759 10,787 +28 (+0.3%)
machine.handle (3 states, 2 transitions) 28,191 28,551 +360 (+1.3%)
fluent transition (10 named branches) 112,798 122,775 +9,977 (+8.8%)
fluent invocation (state-dependent Effect) 99,552 108,429 +8,877 (+8.9%)
machine.handle (depth 24) 199,402 207,970 +8,568 (+4.3%)
machine.handle (wide depth 16) 227,764 236,332 +8,568 (+3.8%)
machine.handle (parallel/history/choice) 135,182 144,812 +9,630 (+7.1%)
machine definition (3 independent implementations) 134,256 143,617 +9,361 (+7.0%)
machine exact input/output/error/services 120,715 129,873 +9,158 (+7.6%)
execution adapter readiness 127,375 136,469 +9,094 (+7.1%)

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,712 7,740 +28 (+0.4%)
machine.handle (3 states, 2 transitions) 17,432 17,764 +332 (+1.9%)
fluent transition (10 named branches) 102,549 112,498 +9,949 (+9.7%)
fluent invocation (state-dependent Effect) 90,287 99,018 +8,731 (+9.7%)
machine.handle (depth 24) 178,706 187,474 +8,768 (+4.9%)
machine.handle (wide depth 16) 208,275 217,043 +8,768 (+4.2%)
machine.handle (parallel/history/choice) 114,919 124,167 +9,248 (+8.0%)
machine definition (3 independent implementations) 118,287 127,576 +9,289 (+7.9%)
machine exact input/output/error/services 106,204 115,217 +9,013 (+8.5%)
execution adapter readiness 97,562 106,299 +8,737 (+9.0%)
Check times (informational)
Scenario Base PR
Effect only 0.03s 0.03s
Import effect-machine 0.03s 0.03s
Machine.states (3 states) 0.10s 0.10s
Machine.make (3 states, 2 events) 0.15s 0.18s
machine.handle (3 states, 2 transitions) 0.24s 0.24s
fluent transition (10 named branches) 0.49s 0.53s
fluent invocation (state-dependent Effect) 0.48s 0.52s
machine.handle (depth 24) 0.72s 0.78s
machine.handle (wide depth 16) 0.81s 0.80s
machine.handle (parallel/history/choice) 0.62s 0.63s
machine definition (3 independent implementations) 0.61s 0.65s
machine exact input/output/error/services 0.57s 0.60s
execution adapter readiness 0.58s 0.59s

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

@SandroMaglione
SandroMaglione force-pushed the codex/combined-state-updates branch from 4520d17 to ed7daaa Compare August 23, 2026 11:55
@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 103,433 transitions/s
Drain burst with terminal fence 312,433 increments/s
Drain burst with a change observer 294,731 increments/s
Lookup and send to one child 268,670 increments/s
Start and stop a machine 133,672 machines/s
Start and stop a parent with one child 39,021 families/s
Plan transitions through a compound state 93,587 transitions/s
Plan transitions through parallel regions 77,950 transitions/s
Drain burst through a compound state 258,905 events/s
Drain burst through two parallel regions 266,313 events/s
Drain a compound-state burst with a change observer 245,064 events/s

Process runtime reference points

Scenario Effect Machine
Start and stop a raw generic process 25,467 processes/s
Start and stop a raw compiled process 64,214 processes/s
Memory profile Effect Machine
Idle machine 1.8 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 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 110,711 transitions/s 0.6% MAD 103,433 transitions/s 1.1% MAD -6.6%
Drain burst with terminal fence 327,132 increments/s 1.7% MAD 312,433 increments/s 0.6% MAD -4.5%
Drain burst with a change observer 308,042 increments/s 2.9% MAD 294,731 increments/s 0.3% MAD -4.3%
Lookup and send to one child 283,297 increments/s 2.0% MAD 268,670 increments/s 0.3% MAD -5.2%
Start and stop a machine 134,048 machines/s 0.4% MAD 133,672 machines/s 0.3% MAD -0.3%
Start and stop a parent with one child 39,672 families/s 0.6% MAD 39,021 families/s 1.1% MAD -1.6%
Plan transitions through a compound state 96,707 transitions/s 1.3% MAD 93,587 transitions/s 0.9% MAD -3.2%
Plan transitions through parallel regions 81,176 transitions/s 0.5% MAD 77,950 transitions/s 1.3% MAD -4.0%
Drain burst through a compound state 272,967 events/s 1.2% MAD 258,905 events/s 1.1% MAD -5.2%
Drain burst through two parallel regions 279,592 events/s 1.5% MAD 266,313 events/s 0.2% MAD -4.7%
Drain a compound-state burst with a change observer 260,935 events/s 0.3% MAD 245,064 events/s 1.7% MAD -6.1%
Idle machine heap per unit 1.8 KiB 0.3% MAD 1.8 KiB 0.1% MAD -0.1%
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.1% MAD 3.2 KiB 0.0% MAD +0.0%
Two independent idle machines heap per unit 3.4 KiB 0.0% MAD 3.4 KiB 0.0% 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.2%

Process runtime reference change from base

Metric Base Base variability PR PR variability Difference
Start and stop a raw generic process 25,292 processes/s 2.6% MAD 25,467 processes/s 4.0% MAD +0.7%
Start and stop a raw compiled process 65,053 processes/s 0.2% MAD 64,214 processes/s 0.5% MAD -1.3%

Regression guard

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

Versions and interpretation
  • Effect Machine: 0.21.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 6d080f5 into main Aug 23, 2026
8 checks passed
@SandroMaglione
SandroMaglione deleted the codex/combined-state-updates branch August 23, 2026 12:40
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