Intent
Let users create durable tasks that run in response to provider events, such as a GitHub webhook event or a Sentry alert.
This complements scheduled tasks:
- A scheduled task runs when its schedule is due.
- An event-triggered task runs when a normalized provider event matches its trigger.
- Both should use the same durable agent dispatch and task-bound credential rules where practical.
Provider webhooks are one source of events, but the task model should depend on normalized events rather than raw webhook payloads.
User experience
Junior should provide tools analogous to the scheduler:
- create an event-triggered task
- list event-triggered tasks
- update an event-triggered task
- delete an event-triggered task
Pause and resume controls are not required.
A task contains:
- creator and destination
- task instruction
- credential mode
- provider
- provider-defined event type or types
- provider-defined resource or scope
- internal lifecycle and run state
Example:
Whenever GitHub reports requested changes on a pull request in getsentry/junior, investigate and address the feedback.
Provider contract
A provider plugin should be able to:
- Own and authenticate its webhook or other event ingress.
- Register the normalized event types and resource/scope types it supports.
- Validate and normalize inbound payloads.
- Publish bounded provider events through Junior core.
- Expose authorized event-source hints that Junior can use when creating a task.
Normalized events should contain stable identity and bounded prompt-safe context, not raw webhook payloads. Provider text must remain explicitly untrusted.
Existing resource event subscriptions and event-triggered tasks should consume the same normalized events:
- Resource subscriptions are temporary watches that route updates into an existing conversation.
- Event-triggered tasks are durable instructions that create a task run for every matching event.
Matching and fan-out
Matching should initially be exact:
- provider
- registered event type
- provider-issued resource or scope reference
Do not introduce an arbitrary payload filter language in the first version.
One event may match any number of tasks. Each matching task creates an independent run. Duplicate delivery protection is scoped to taskId + eventKey; processing an event for one task must not prevent other matching tasks from running.
Events may need both a primary resource and parent scopes. For example, a pull request review event can identify its pull request while also matching repository-scoped tasks.
Execution and reliability
- Verify and durably enqueue an event before acknowledging ingress.
- Execute task runs outside the webhook request.
- Use a durable run record and idempotent agent dispatch.
- Snapshot the task instruction and trigger version onto the run.
- Keep creator and destination immutable during updates.
- Bound concurrent and pending runs so event storms cannot create unlimited work.
- Block a task internally when credentials or configuration make it unrunnable.
- Protect against feedback loops where a task action causes another matching event.
- Preserve independent failures: one task failure must not stop fan-out to other matching tasks.
Permissions and credentials
Permissions should follow the scheduler's model:
- Users may manage only tasks they are authorized to manage in the applicable conversation.
- Provider plugins must validate that the creator may register a task for the requested resource or scope; guessing a scope reference is not authorization.
- System credentials are the default.
- Creator credentials require explicit authorization for future runs.
- Core binds delegated credentials to the exact event-triggered task ID.
- Provider events are system-authored input, never user-authored commands.
Proposed ownership
- Junior core owns durable normalized event ingress, fan-out boundaries, task credential enforcement, and shared dispatch primitives.
- Provider plugins own webhook verification, normalization, registered event types, scopes, and scope authorization.
- A new
@sentry/junior-event-tasks package owns task authoring tools, persistence, event matching, runs, and operational reporting.
- The scheduler continues to own cadence and due-run selection. Event matching should not be added to the scheduler.
- Scheduled and event-triggered tasks may share UI and execution primitives without sharing trigger implementations.
Initial vertical slice
Use GitHub first because it already has signed webhook ingress and normalized resource events:
- Define the plugin event registration and authorized event-source contracts.
- Extend normalized GitHub events with repository scope where needed.
- Add event task and run persistence.
- Add create, list, update, and delete tools.
- Support one repository-scoped GitHub event, such as
review.changes_requested.
- Dispatch every matching task independently.
- Cover duplicate deliveries, multiple matching tasks, authorization, deletion, task updates, partial fan-out failures, and event storms.
- Add Sentry webhook ingress and normalized Sentry event sources after the contract is proven.
Open design questions
- Exact plugin API for registering event and scope definitions.
- How authorized event-source hints are represented and revalidated at creation.
- Whether normalized events extend
resourceRef with parent scopeRefs or use another bounded routing shape.
- Exact durable queue boundary and retry policy.
- Which scheduler execution and credential-binding primitives should move into core.
Non-goals for the first version
- Arbitrary filtering over raw webhook payloads.
- User-facing pause and resume controls.
- Running agent work directly inside webhook handlers.
- Coupling event-triggered tasks to scheduler cadence.
- Requiring only one task per event.
Intent
Let users create durable tasks that run in response to provider events, such as a GitHub webhook event or a Sentry alert.
This complements scheduled tasks:
Provider webhooks are one source of events, but the task model should depend on normalized events rather than raw webhook payloads.
User experience
Junior should provide tools analogous to the scheduler:
Pause and resume controls are not required.
A task contains:
Example:
Provider contract
A provider plugin should be able to:
Normalized events should contain stable identity and bounded prompt-safe context, not raw webhook payloads. Provider text must remain explicitly untrusted.
Existing resource event subscriptions and event-triggered tasks should consume the same normalized events:
Matching and fan-out
Matching should initially be exact:
Do not introduce an arbitrary payload filter language in the first version.
One event may match any number of tasks. Each matching task creates an independent run. Duplicate delivery protection is scoped to
taskId + eventKey; processing an event for one task must not prevent other matching tasks from running.Events may need both a primary resource and parent scopes. For example, a pull request review event can identify its pull request while also matching repository-scoped tasks.
Execution and reliability
Permissions and credentials
Permissions should follow the scheduler's model:
Proposed ownership
@sentry/junior-event-taskspackage owns task authoring tools, persistence, event matching, runs, and operational reporting.Initial vertical slice
Use GitHub first because it already has signed webhook ingress and normalized resource events:
review.changes_requested.Open design questions
resourceRefwith parentscopeRefsor use another bounded routing shape.Non-goals for the first version