Skip to content

Fix invoke owner protocol inference - #134

Merged
SandroMaglione merged 1 commit into
mainfrom
codex/fix-invoke-contextual-protocols
Aug 17, 2026
Merged

Fix invoke owner protocol inference#134
SandroMaglione merged 1 commit into
mainfrom
codex/fix-invoke-contextual-protocols

Conversation

@SandroMaglione

Copy link
Copy Markdown
Member

Summary

  • contextually type Machine.invoke sources and lifecycle handlers with the owning machine public and parent protocols inside .handle(...)
  • retain Effect output, failure, service, state, and child protocol inference while rejecting invalid parent or self sends
  • teach direct event protocol construction in API docs, the agent guide, README, and examples

Changeset

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

Patch changeset: compatible inference and documentation fix.

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

Affected examples checked: playground, pokemon, and platformer. Local pnpm perf:types and pnpm perf:runtime smoke tests passed; CI base-versus-PR comparisons remain authoritative.

@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.defineStates (3 states) 3,039 3,039 0 (0.0%)
Machine.make (3 states, 2 events) 10,439 10,439 0 (0.0%)
machine.handle (3 states, 2 transitions) 53,206 53,206 0 (0.0%)
Machine.transition (10 conditional cases) 116,110 116,110 0 (0.0%)
Machine.invoke (state-dependent Effect) 57,187 57,606 +419 (+0.7%)
machine.handle (depth 24) 188,289 188,289 0 (0.0%)
machine.handle (wide depth 16) 219,355 219,355 0 (0.0%)
machine.handle (parallel/history/choice) 132,085 132,085 0 (0.0%)
machine.handle (4 successive calls) 137,762 137,762 0 (0.0%)
machine exact input/output/error/services 114,832 114,832 0 (0.0%)
execution adapter readiness 124,664 124,748 +84 (+0.1%)

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) 7,392 7,392 0 (0.0%)
machine.handle (3 states, 2 transitions) 42,767 42,767 0 (0.0%)
Machine.transition (10 conditional cases) 106,181 106,181 0 (0.0%)
Machine.invoke (state-dependent Effect) 48,341 48,760 +419 (+0.9%)
machine.handle (depth 24) 168,599 168,599 0 (0.0%)
machine.handle (wide depth 16) 200,664 200,664 0 (0.0%)
machine.handle (parallel/history/choice) 112,409 112,409 0 (0.0%)
machine.handle (4 successive calls) 122,216 122,216 0 (0.0%)
machine exact input/output/error/services 100,741 100,741 0 (0.0%)
execution adapter readiness 62,727 62,811 +84 (+0.1%)
Check times (informational)
Scenario Base PR
Effect only 0.03s 0.04s
Import effect-machine 0.04s 0.03s
Machine.defineStates (3 states) 0.11s 0.11s
Machine.make (3 states, 2 events) 0.18s 0.18s
machine.handle (3 states, 2 transitions) 0.36s 0.34s
Machine.transition (10 conditional cases) 0.56s 0.58s
Machine.invoke (state-dependent Effect) 0.40s 0.42s
machine.handle (depth 24) 0.78s 0.80s
machine.handle (wide depth 16) 0.80s 0.81s
machine.handle (parallel/history/choice) 0.65s 0.66s
machine.handle (4 successive calls) 0.66s 0.64s
machine exact input/output/error/services 0.59s 0.61s
execution adapter readiness 0.58s 0.57s

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 145,659 transitions/s
Drain burst with terminal fence 428,964 increments/s
Drain burst with a change observer 402,293 increments/s
Lookup and send to one child 369,223 increments/s
Start and stop a machine 175,162 machines/s
Start and stop a parent with one child 53,769 families/s
Plan transitions through a compound state 126,738 transitions/s
Plan transitions through parallel regions 104,384 transitions/s
Drain burst through a compound state 353,965 events/s
Drain burst through two parallel regions 358,329 events/s
Drain a compound-state burst with a change observer 336,618 events/s

Process runtime reference points

Scenario Effect Machine
Start and stop a raw generic process 34,731 processes/s
Start and stop a raw compiled process 84,260 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 143,416 transitions/s 0.8% MAD 145,659 transitions/s 2.0% MAD +1.6%
Drain burst with terminal fence 420,644 increments/s 1.4% MAD 428,964 increments/s 1.1% MAD +2.0%
Drain burst with a change observer 392,940 increments/s 1.8% MAD 402,293 increments/s 1.6% MAD +2.4%
Lookup and send to one child 359,208 increments/s 0.8% MAD 369,223 increments/s 0.6% MAD +2.8%
Start and stop a machine 176,710 machines/s 0.6% MAD 175,162 machines/s 1.2% MAD -0.9%
Start and stop a parent with one child 53,000 families/s 0.5% MAD 53,769 families/s 1.0% MAD +1.5%
Plan transitions through a compound state 125,761 transitions/s 0.7% MAD 126,738 transitions/s 1.1% MAD +0.8%
Plan transitions through parallel regions 102,659 transitions/s 1.1% MAD 104,384 transitions/s 1.4% MAD +1.7%
Drain burst through a compound state 351,285 events/s 1.4% MAD 353,965 events/s 0.4% MAD +0.8%
Drain burst through two parallel regions 357,944 events/s 2.7% MAD 358,329 events/s 0.4% MAD +0.1%
Drain a compound-state burst with a change observer 333,756 events/s 0.8% MAD 336,618 events/s 0.5% MAD +0.9%
Idle machine heap per unit 1.8 KiB 0.4% MAD 1.8 KiB 0.0% MAD -0.2%
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.2% MAD 3.1 KiB 0.1% MAD +0.1%
Two independent idle machines heap per unit 3.4 KiB 0.0% MAD 3.4 KiB 0.0% MAD +0.7%
Idle parent with one child heap per unit 5.5 KiB 0.0% MAD 5.5 KiB 0.0% MAD +0.0%
Parent with observed child registry heap per unit 9.7 KiB 0.0% MAD 9.7 KiB 0.0% MAD -0.0%
Parent with observed invoked child snapshots heap per unit 6.1 KiB 0.0% MAD 6.1 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 34,826 processes/s 3.1% MAD 34,731 processes/s 0.6% MAD -0.3%
Start and stop a raw compiled process 83,907 processes/s 1.2% MAD 84,260 processes/s 0.7% MAD +0.4%

Regression guard

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

Versions and interpretation
  • Effect Machine: 0.14.1

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 4dd8d24 into main Aug 17, 2026
13 checks passed
@SandroMaglione
SandroMaglione deleted the codex/fix-invoke-contextual-protocols branch August 17, 2026 14:23
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