Workbench Subscriptions — Design
Date: 2026-10-15 Status: Approved in discussion; awaiting spec review
Goal
Let a workbench composition define the subscriptions that trigger its workflow, so the workbench goes from a goal to working automation. Publishing never turns automation on: the user enables each published subscription explicitly.
Decisions
| Topic | Decision |
|---|---|
| Item type | New composition item type subscription, any number per composition |
| Routing | create-workflow rules must target the composition's own workflow; workflow-dispatch rules allowed |
| Going live | Publish creates/updates subscriptions disabled; an explicit Enabled switch in the workbench enables |
Draft enabled |
Not part of the draft; ignored on publish, with a validation warning |
| Enabling | Sets enabled = true and processEventsFrom = now (no backlog) |
| Republish | Never changes a published subscription's enabled state |
| Removing a draft / deleting the composition | Published subscription untouched (same as other item types) |
| Filter preview | Existing POST /subscriptions/preview over the 200 most recent events, plus error info; AI tool preview_subscription and a UI panel |
Current State (for reference)
- Composition item types are
workflow,action-type,tool(CompositionItemssupported set). Publishing builds a configuration pack and callsImportExportService.importOrUpdatePack, which already imports subscriptions (ConfigItemType.SUBSCRIPTION, pack arraysubscriptions). - Subscriptions (
EventSubscriptionEntity):name,description,enabled,filters(EL filter),routing(JSON rules),processEventsFrom(defaults to creation time),labels. Pack/item JSON usesfilterExpressionfor the filter. - Routing rules:
create-workflow(workflowDefinitionNameorworkflowDefinitionId) starts runs;workflow-dispatch(no target) delivers events to every run waiting at a matchingreceive-eventnode. Without aworkflow-dispatchsubscription, receive-event nodes never receive events. - Subscription matching:
SubscriptionFilterEvaluator.matchesoverEventStreamOrchestrator.filterEventMap(errors count as no match).ExpressionServicealready has asubscription-filterscope.
1. Subscription Items
subscriptionjoins the supported composition item types. Content is the pack form:{name, description, filterExpression, routing, labels}.- The workbench AI creates and edits them with the existing
upsert_item(type: "subscription"); the user edits them in a form editor (Section 6). - An
enabledfield in a draft is ignored and reported as a warningENABLED_IGNORED: "Subscriptions are published disabled; enable them in the workbench after publishing." - New empty subscription items are created with
filterExpression: "",routing: [].
2. Validation (composition context, on top of existing subscription validation)
- Error
FOREIGN_WORKFLOW_ROUTE: acreate-workflowrule that does not useworkflowDefinitionNameequal to the name of the composition's workflow item (rules withworkflowDefinitionId, or another name). workflow-dispatchrules are allowed without further checks.- Warning
OVERLAPPING_SUBSCRIPTION: another enabled published subscription, not owned by this composition, has acreate-workflowrule for this composition's workflow. - Publish dependency: a subscription item requires the composition's workflow to be published already or selected in the same publish (same mechanism as action types requiring tools).
3. Publishing and Enabling
- Publish passes subscriptions through the existing pack import. Before import it removes
enabledandprocessEventsFromfrom each subscription pack item and sets them from the published subscription (when one exists) or toenabled: false(new;processEventsFromthen defaults to creation time). The import's update path otherwise resetsenabledto false. - The published-content revision used for "changed outside the workbench" detection excludes
enabledandprocessEventsFrom, so toggling the switch is not an outside change. - New endpoint (contract-first):
PUT /compositions/{compositionId}/items/{itemId}/enabledwith body{"enabled": boolean}. - 404 when the item is not in the composition; 409 when it is not a subscription or not yet published.
true: setsenabled = trueandprocessEventsFrom = now.false: setsenabled = false.- Returns the item, including its published subscription's
enabledstate. - Composition item responses gain
enabled(boolean, only for published subscription items) so the UI can show the switch state. - The Events → Subscriptions page is unchanged; changes made there are reflected in the switch.
4. Filter Preview
- Reuse the existing
POST /subscriptions/preview(previewSubscriptionFilter; used today by the Subscriptions page) with{"filterExpression": ..., "limit": 200}: it evaluates the filter against the most recent events (bytimestamp) and returns each withmatched, plustotalMatchedover all events. - Extend its response (contract-first, backward compatible) with
errorCount(events on this page whose evaluation threw) andfirstError(that first error message). Matching semantics are unchanged (an error is no match), so the Subscriptions page behaves as before. - AI tool
preview_subscription(filterExpression)in the workbench MCP server: calls the endpoint withlimit: 200and formats "N of M recent events match", the error count/first error, and up to 20 matches (type, ref, actor login, timestamp), one line each.
5. Workbench AI
- Allowed tools gain
mcp__workbench__preview_subscription. - Workbench reference gains a Subscriptions section:
- a composition may define subscriptions (
upsert_itemtypesubscription); create-workflowonly to this composition's workflow, byworkflowDefinitionName;- add a
workflow-dispatchsubscription whenever the workflow has receive-event nodes; - check filters with
preview_subscription(and single events withevaluate_expression, scopesubscription-filter); - do not set
enabled: publishing leaves subscriptions disabled and the user enables them. - New prompt rule: "Never say the automation is live: published subscriptions stay disabled until the user enables them in the workbench."
6. UI
- Composition tree: a Subscriptions group listing subscription items; "add" creates an empty item.
- Subscription editor: name, description, filter expression (monospace text area), routing rules (type select;
create-workflowfixed to the composition's workflow), labels; and a Matching events panel that calls the preview endpoint for the current filter (debounced) and shows "N of 200 recent events match", errors, and the matched events linking to/events/stream/{id}. - An Enabled switch in the subscription editor header, shown only when the item is published; disabled with a tooltip when the composition's workflow is not published.
7. Testing
- Backend: item type supported;
FOREIGN_WORKFLOW_ROUTE,ENABLED_IGNORED,OVERLAPPING_SUBSCRIPTION; publish dependency; publish creates disabled and preserves enabled on update; enable/disable endpoint (404/409,processEventsFromset on enable); preview endpoint (matches, errors, limit 200). - Workbench MCP:
preview_subscriptionformatting (Node test); reference and prompt tests. - UI: tree group, editor fields, Matching events panel, Enabled switch states.
Out of Scope
- Event sources (credentials, webhooks) in the workbench.
- Disabling or deleting published subscriptions when drafts or compositions are removed.
- Workbench test runs of subscriptions.