Problem
Event emission currently has two paths (Context.WriteEvent and Context.EventSink) and some implementations accept ScriptBlock sinks that get invoked directly. This is both confusing (inconsistent behavior across pipeline/host) and a security risk (potential RCE if an untrusted sink is passed through).
Goal
Provide one supported engine eventing path with a clear, testable contract:
- Engine calls
Context.EventSink.WriteEvent($event) (or equivalent) only.
- No direct invocation of ScriptBlocks by the engine.
Proposed design
- Introduce a sink contract (PowerShell-friendly):
Context.EventSink MUST be an object that implements WriteEvent([object] $event) (or WriteEvent([IdleEvent]$event) if type exists).
- Engine validates that
EventSink is not a ScriptBlock and has a callable WriteEvent member.
- Deprecate and later remove
Context.WriteEvent.
- During transition: map
Context.WriteEvent -> adapter sink internally (opt-in / compatibility) OR keep for one release with warning.
- Update
Write-IdleEvent to use the sink contract only.
Acceptance criteria
Notes
This change is expected to be a breaking-change unless we provide a short-lived compatibility shim.
Problem
Event emission currently has two paths (
Context.WriteEventandContext.EventSink) and some implementations acceptScriptBlocksinks that get invoked directly. This is both confusing (inconsistent behavior across pipeline/host) and a security risk (potential RCE if an untrusted sink is passed through).Goal
Provide one supported engine eventing path with a clear, testable contract:
Context.EventSink.WriteEvent($event)(or equivalent) only.Proposed design
Context.EventSinkMUST be an object that implementsWriteEvent([object] $event)(orWriteEvent([IdleEvent]$event)if type exists).EventSinkis not a ScriptBlock and has a callableWriteEventmember.Context.WriteEvent.Context.WriteEvent-> adapter sink internally (opt-in / compatibility) OR keep for one release with warning.Write-IdleEventto use the sink contract only.Acceptance criteria
IdLE.Step.EmitEvent(and demos) emit events using the unified sink path.Notes
This change is expected to be a breaking-change unless we provide a short-lived compatibility shim.