Skip to content

fix: Forward the gated event from the Time Gate - #6873

Open
claykaufmann wants to merge 1 commit into
superplanehq:mainfrom
claykaufmann:fix/time-gate-forwards-gated-event
Open

claykaufmann wants to merge 1 commit into
superplanehq:mainfrom
claykaufmann:fix/time-gate-forwards-gated-event

Conversation

@claykaufmann

Copy link
Copy Markdown

Summary

The Time Gate drops the event payload whenever it actually gates.

The component emits from two paths:

  • Execute() emits the incoming event when the current time is already inside the active window (time_gate.go#L176).
  • HandleTimeReached and HandlePushThrough emit when the gate waited. Hooks run with an ActionHookContext, which does not carry the event data, so both sent a literal map[string]any{}.

ExecutionStateContext.Emit writes that payload directly to the data field of the event that downstream nodes consume, and PassInTransaction adds no fallback. Downstream nodes therefore receive {}, and every expression that reads the gate output resolves to nothing.

The failure is silent and depends on timing. The same canvas keeps the payload when the run starts inside the window and drops it when the gate defers. Deferring is the normal case, so a "release at 09:00" gate loses the payload every day, while a manual test run during business hours looks correct.

This also contradicts the component documentation, which describes the gate as delaying event processing rather than replacing the event.

Fix

Store the event in the execution metadata when the gate defers, then emit that event from both hooks. Executions that stored no event keep the previous empty object, so executions already in flight during a deploy stay valid.

The change stays inside the component. Adding Data to core.ActionHookContext would work too, but it touches the framework and the other hook-based components synthesize their own payloads on purpose.

Test plan

  • TestTimeGate_TimeReached_ForwardsGatedEvent — the gate defers, then timeReached emits the original event. Fails on main with data = {}.
  • TestTimeGate_PushThrough_ForwardsGatedEvent — same for the manual push-through action.
  • TestTimeGate_ForwardsGatedEventStoredAsJSON — the payload survives the JSON round trip that ExecutionMetadataContext performs.
  • TestTimeGate_EmitsEmptyObjectWhenNoEventStored — executions with no stored event still emit {}.
  • The existing Time Gate tests pass unchanged.
  • gofmt and go vet are clean for the package.
  • docs/components/Core.mdx is updated for the new documentation line.

The new tests select tomorrow as the only active day, so the gate always defers and the tests do not depend on the wall-clock time at which CI runs them.

The Time Gate emitted an empty object when it released an event that it
had held. Downstream nodes received no payload, so every expression that
read the gate output resolved to nothing.

The component emits from two paths. Execute() emits the incoming event
when the current time is already inside the window. The timeReached and
pushThrough hooks emit when the gate actually waited, but hooks run with
an ActionHookContext, which does not carry the event data. Both hooks
sent a literal empty map instead.

The result was silent and depended on timing: the same canvas kept the
payload when the window was open and dropped it when the gate deferred.

Store the event in the execution metadata when the gate defers, then
emit that event from both hooks. Executions with no stored event keep
the previous empty object, so in-flight executions stay valid.

Signed-off-by: Clay Kaufmann <claykaufmann@gmail.com>
@superplanehq-integration

Copy link
Copy Markdown
Contributor

👋 Commands for maintainers:

  • /sp start - Start an ephemeral machine (takes ~30s)
  • /sp stop - Stop a running machine (auto-executed on pr close)

@superplanehq-integration

Copy link
Copy Markdown
Contributor

Maintainers: comment /deploy-storybook to get a Storybook link for this PR.

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