diff --git a/docs/meta/backlog.md b/docs/meta/backlog.md
index b8ec1a2..a510fdc 100644
--- a/docs/meta/backlog.md
+++ b/docs/meta/backlog.md
@@ -4,7 +4,7 @@ This backlog is prioritized by user impact and frequency of complaints
based on gap analysis from 161 issues across elsa-studio and
elsa-gitbook.
-## Slice Inventory (2026-06-19)
+## Slice Inventory (2026-06-20)
This inventory reflects the current GitBook contents before selecting the
next automation slice. "Covered" means the repository now includes a
@@ -35,7 +35,7 @@ acceptance criterion below is already complete.
- `DOC-022` Scaling and performance
- `DOC-024` MassTransit communication
- `DOC-040` Timer and scheduled workflows
-- `DOC-042` Bulk dispatch workflows activity
+- `DOC-053` Alterations operational guide hardening
- `DOC-028` Studio customization
- `DOC-029` Custom UI hints
- `DOC-030` Custom UI components
@@ -52,25 +52,25 @@ acceptance criterion below is already complete.
- `DOC-027` Execution model
- `DOC-038` Distributed tracing
- `DOC-039` Performance tuning
+- `DOC-042` Bulk dispatch workflows activity
- `DOC-043` Hangfire integration
- `DOC-047` API reference
- `DOC-048` Activity reference
-- `DOC-053` Alterations operational guide hardening
### Current run selection
-- `DOC-042` Bulk dispatch workflows activity: add a release-backed guide that
- explains fan-out child workflow dispatch, item-to-input mapping,
- `WaitForCompletion`, per-child ports, and how the activity differs from the
- REST bulk-dispatch endpoint.
+- `DOC-053` Alterations operational guide hardening: rewrite the alterations
+ pages around the actual `release/3.8.0` execution modes, built-in alteration
+ types, plan lifecycle, Studio surfaces, persistence options, and shipped HTTP
+ endpoints including bulk retry.
### Recommended next slice
-- `DOC-025` Long-running workflows: the new scheduling guide now explains
- timers and durable resumes, but the docs still lack one release-backed guide
- that connects bookmarks, timers, incidents, cancellation, persistence,
- background execution, and operator troubleshooting into a full workflow
- lifecycle narrative.
+- `DOC-019` HTTP endpoint security: the HTTP workflow guides now explain how
+ to build endpoints, but the auth surface is still spread across multiple
+ pages. A single release-backed guide should connect `Authorize`,
+ `HttpEndpoint`, API permissions, public vs authenticated endpoints, and
+ Studio-facing troubleshooting.
### Newly discovered follow-on topics
@@ -84,35 +84,27 @@ acceptance criterion below is already complete.
- `DOC-052` Workflow state and journal API cookbook: add an operations-facing
guide for inspecting workflow state, filtered journal entries, activity
executions, and variable mutation endpoints when diagnosing live instances.
-- `DOC-054` Messaging transport decision guide: document when to use
- MassTransit message-type activities, the Azure Service Bus activity module,
- or MassTransit-backed workflow dispatching so teams do not conflate three
- different messaging integration paths.
+- `DOC-054` Messaging transport selection and topology guide: add a focused
+ cross-cutting guide that helps architects choose between MassTransit,
+ Azure Service Bus, and Kafka extensions, and explains when to use
+ workflow-trigger activities vs runtime dispatchers vs custom consumers.
### Current run result
-- `DOC-040` Timer and scheduled workflows: completed in this run by adding a
- dedicated guide for `Delay`, `StartAt`, `Timer`, and `Cron`, and grounding
- the scheduling model in `DefaultBookmarkScheduler`, `ResumeWorkflowTask`,
- `LocalScheduler`, and Quartz-backed scheduler configuration from
- `release/3.8.0`.
-- `DOC-042` Bulk dispatch workflows activity: completed in this run by adding
- a dedicated guide for `BulkDispatchWorkflows`, clarifying item input mapping,
- wait-vs-fire-and-forget behavior, per-child completion and fault ports,
- channel dispatch, and the difference between in-workflow bulk dispatch and
- the `/workflow-definitions/{definitionId}/bulk-dispatch` API endpoint.
+- `DOC-053` Alterations operational guide hardening: completed in this run by
+ aligning the overview, alteration plans, and immediate execution guides with
+ `release/3.8.0` behavior, including Studio's alterations module, the
+ built-in `Cancel` alteration, persistence and dispatcher configuration, the
+ `run:alterations` permission surface, and the shipped `/alterations/run`,
+ `/alterations/submit`, `/alterations/dry-run`, and
+ `/alterations/workflows/retry` endpoints.
## Critical Priority (Must Have - Block Users)
### Current slice note
- `DOC-053` Alterations operational guide hardening:
- `features/alterations` is present, but the current pages are not fully
- release-backed. Examples still use pre-filter plan payloads, omit the built-in
- `Cancel` alteration, describe `/alterations/run` as requiring manual resume
- dispatch even though the endpoint already dispatches successful instances with
- scheduled work, and do not explain the Studio alterations surface or the
- persistence/dispatcher options available in `release/3.8.0`.
+ completed on 2026-06-20.
### DOC-001: V2 to V3 Migration Guide
- **Persona**: Backend Integrator, Architect
diff --git a/features/alterations/README.md b/features/alterations/README.md
index 41e8f0e..030fd52 100644
--- a/features/alterations/README.md
+++ b/features/alterations/README.md
@@ -4,6 +4,17 @@ An [alteration](../../getting-started/concepts/#alteration) represents a change
Using alterations, you can change the state of a running workflow instance without republishing the workflow definition. In `release/3.8.0`, Elsa exposes alterations through server APIs and Elsa Studio.
+## What Elsa ships in `release/3.8.0`
+
+Enabling `UseAlterations()` adds:
+
+* the built-in `Elsa.Alterations.ExecuteAlterationPlan` system workflow used to execute submitted plans
+* REST endpoints under `/alterations`
+* in-memory alteration plan and job stores by default
+* an in-memory background dispatcher for alteration jobs by default
+
+All alteration APIs shown on this page require the `run:alterations` permission.
+
## When to use alterations
Use alterations when you need to correct or steer existing workflow instances. Typical examples include:
@@ -35,15 +46,34 @@ Use these pages for each mode:
* [Alteration Plans](alteration-plans/README.md)
* [Applying Alterations](applying-alterations/README.md)
+### Which mode fits which job
+
+| Situation | Use |
+| --- | --- |
+| You already know the exact workflow instance IDs and need the response now | `POST /alterations/run` or `IAlterationRunner` |
+| You need Elsa to find matching workflow instances from filters and process them in the background | alteration plans |
+| You need to retry faulted activities across one or more instances | `POST /alterations/workflows/retry` |
+| You want designers or operators to stage a bulk plan visually in Studio | Elsa Studio alterations module |
+
## Elsa Studio
Elsa Studio in `release/3.8.0` includes an alterations module. When the backend Alterations feature is enabled, Studio shows an **Alterable instances** page and adds **Alter** actions for running workflow instances.
-Studio currently focuses on altering individual running instances. For bulk operations across many instances, use alteration plans and their filter-based API.
+Studio exposes:
+
+* an **Alterations** top-level menu with plan and instance views
+* an **Alterable instances** page that lists non-system running workflow instances
+* an alteration designer for staging the five built-in alteration types against an instance
+* plan details pages that show plan status, generated jobs, and per-job logs
+* quick **Alter** actions from workflow-instance screens
+
+Studio currently focuses on staging or inspecting plans around individual running instances. For cross-instance bulk operations, use alteration plans and their filter-based API.
## Persistence and dispatch options
-By default, Alterations uses in-memory stores and an in-memory background dispatcher. For durable or multi-node deployments, configure persistence for alteration plans and jobs:
+By default, Alterations uses in-memory stores and an in-memory background dispatcher. That is fine for local development, but plans and jobs are not durable across process restarts.
+
+For durable or multi-node deployments, configure persistence for alteration plans and jobs:
```csharp
services.AddElsa(elsa => elsa.UseAlterations(alterations =>
@@ -69,3 +99,13 @@ services.AddElsa(elsa => elsa.UseAlterations(alterations =>
alterations.UseMassTransitDispatcher();
}));
```
+
+Use the MassTransit dispatcher when alteration jobs should survive node boundaries or be processed by worker nodes connected through MassTransit. The dispatcher replaces the default in-memory background queue for alteration jobs only; it does not change how the immediate `/alterations/run` endpoint executes.
+
+## Operational notes
+
+* Submitted plans create one alteration job per matched workflow instance.
+* If a submitted plan matches no instances, Elsa still stores the plan but generates no jobs.
+* `/alterations/run` dispatches successful workflow instances that still have scheduled work after the alterations finish.
+* `IAlterationRunner` by itself does not dispatch scheduled work; pair it with `IAlteredWorkflowDispatcher` when you call the service directly.
+* The built-in bulk retry endpoint schedules faulted activities by creating `ScheduleActivity` alterations and then dispatching the affected instances.
diff --git a/features/alterations/alteration-plans/README.md b/features/alterations/alteration-plans/README.md
index 3cc8bbd..7f00902 100644
--- a/features/alterations/alteration-plans/README.md
+++ b/features/alterations/alteration-plans/README.md
@@ -15,6 +15,19 @@ In `release/3.8.0`, `IAlterationPlanScheduler` accepts `AlterationPlanParams`, w
* `filter`: an `AlterationWorkflowInstanceFilter` describing which workflow instances to target
* `id`: an optional plan ID; Elsa generates one when omitted
+## What happens when you submit a plan
+
+Submitting a plan does not run the alterations inline with the request. Elsa instead:
+
+1. stores or generates the plan ID
+2. dispatches the built-in `Elsa.Alterations.ExecuteAlterationPlan` system workflow
+3. stores the plan
+4. finds matching workflow instances from the filter
+5. creates one alteration job per matching instance
+6. dispatches those jobs through the configured alteration job dispatcher
+
+This is why alteration plans are the right fit for bulk operational work, scheduled worker processing, and cases where you need job-level inspection later.
+
### Creating Alteration Plans
To create an alteration plan in code, create an `AlterationPlanParams` instance:
@@ -39,6 +52,19 @@ var plan = new AlterationPlanParams
The workflow-instance filter supports more than explicit instance IDs. In `release/3.8.0`, you can also filter by correlation IDs, names, search term, definition IDs, definition version IDs, statuses, sub-statuses, incidents, system-workflow flag, activity filters, and timestamp filters.
+### Filter guidance
+
+Use explicit `workflowInstanceIds` when you already know the exact targets but still want background execution and plan tracking.
+
+Use broader filters when you are operating on a live slice of runtime state, for example:
+
+* all running instances of a specific workflow definition
+* instances with incidents
+* instances waiting in a specific sub-status
+* instances created, updated, or finished in a specific time range
+
+Use `POST /alterations/dry-run` before submitting a broad filter so you can confirm which instance IDs Elsa would target.
+
### Submitting Alteration Plans
To submit an alteration plan, use the `IAlterationPlanScheduler` service. For example:
@@ -65,3 +91,30 @@ var jobs = (await store.FindManyAsync(new AlterationJobFilter { PlanId = planId
```
If the filter matches no workflow instances, Elsa still stores the plan, but it does not create jobs.
+
+## Plan status and job status
+
+The plan and job records are separate on purpose:
+
+* the plan tells you whether Elsa accepted and processed the bulk request
+* the jobs tell you what happened for each targeted workflow instance
+
+Use plan timestamps plus per-job logs to answer operational questions such as:
+
+* did Elsa find any matching instances
+* which instances failed
+* which alteration inside the plan failed for a specific instance
+* whether a plan has finished creating and dispatching its jobs
+
+## Elsa Studio workflow
+
+In Studio, the alterations designer submits the same `AlterationPlanParams` payload used by the server API.
+
+After submission, Studio navigates to a plan details page that shows:
+
+* the stored plan payload
+* current plan status
+* generated jobs
+* per-job log entries
+
+This is the fastest path for operators who want plan visibility without scripting the REST API directly.
diff --git a/features/alterations/alteration-plans/rest-api.md b/features/alterations/alteration-plans/rest-api.md
index ec8884f..e541c4e 100644
--- a/features/alterations/alteration-plans/rest-api.md
+++ b/features/alterations/alteration-plans/rest-api.md
@@ -2,6 +2,8 @@
The Alterations module exposes a REST API for submitting, inspecting, and dry-running alteration plans.
+All endpoints on this page require the `run:alterations` permission.
+
## Submit a plan
Send `POST /alterations/submit` with `alterations` plus a `filter`:
@@ -68,6 +70,21 @@ Example response:
}
```
+The dry-run endpoint accepts the same `AlterationWorkflowInstanceFilter` model that `POST /alterations/submit` uses inside `filter`. In `release/3.8.0`, that includes:
+
+* `workflowInstanceIds`
+* `correlationIds`
+* `names`
+* `searchTerm`
+* `definitionIds`
+* `definitionVersionIds`
+* `statuses`
+* `subStatuses`
+* `hasIncidents`
+* `isSystem`
+* `activityFilters`
+* `timestampFilters`
+
## Get plan and job status
Use the plan ID to query the current plan and its jobs:
@@ -132,3 +149,5 @@ The response includes the stored plan and any generated jobs:
```
`status` values are serialized from Elsa's plan and job status enums. Use the plan timestamps and per-job logs to understand whether Elsa found matching instances, whether jobs have started, and which alterations succeeded or failed.
+
+If a plan matches no workflow instances, the response still returns the stored plan, but `jobs` remains empty.
diff --git a/features/alterations/applying-alterations/README.md b/features/alterations/applying-alterations/README.md
index af6f2fa..cc8088e 100644
--- a/features/alterations/applying-alterations/README.md
+++ b/features/alterations/applying-alterations/README.md
@@ -2,6 +2,8 @@
Use immediate execution when you already know which workflow instance IDs you want to alter and you want the results in the current request.
+This execution mode is synchronous from the caller's point of view: Elsa runs the requested alterations against the specified workflow instances and returns one result per instance.
+
At the service level, immediate execution uses `IAlterationRunner`:
```csharp
@@ -21,6 +23,17 @@ var results = await runner.RunAsync(workflowInstanceIds, alterations, cancellati
This updates the specified workflow instances synchronously and returns one `RunAlterationsResult` per instance.
+## What the result tells you
+
+Each `RunAlterationsResult` contains:
+
+* `workflowInstanceId`
+* `log`
+* `workflowHasScheduledWork`
+* `isSuccessful`
+
+Use the log entries to see which alteration succeeded or failed for each targeted instance.
+
## Resuming scheduled work
When you use `IAlterationRunner` directly, successful alterations may leave workflow instances with scheduled work waiting to be dispatched. In that case, resume them with `IAlteredWorkflowDispatcher`:
@@ -40,3 +53,21 @@ This distinction matters:
* `POST /alterations/run` runs the alterations and then automatically dispatches successful instances that have scheduled work.
If you are using the HTTP API, you do not need a separate resume step after a successful `/alterations/run` request.
+
+## When to use immediate execution
+
+Use immediate execution when:
+
+* an operator already has one or more concrete workflow instance IDs
+* you want the alteration log in the same request
+* you do not need durable plan and job records
+
+Use alteration plans instead when Elsa should discover the target instances for you or when you need persistent plan and job tracking.
+
+## Retrying faulted workflow instances
+
+`release/3.8.0` also ships a bulk retry endpoint for faulted instances: `POST /alterations/workflows/retry`.
+
+That endpoint builds `ScheduleActivity` alterations for the specified activity IDs, or for all incident activity IDs when you omit `activityIds`, then dispatches the updated workflow instances.
+
+Use the retry endpoint when your operational goal is specifically "retry the faulted work" rather than "apply an arbitrary alteration set".
diff --git a/features/alterations/applying-alterations/rest-api.md b/features/alterations/applying-alterations/rest-api.md
index 7c5a3e3..208e528 100644
--- a/features/alterations/applying-alterations/rest-api.md
+++ b/features/alterations/applying-alterations/rest-api.md
@@ -4,6 +4,8 @@ The Alterations module exposes `POST /alterations/run` for immediate execution a
Use this endpoint when you already know the target instance IDs and want the results immediately. If you want Elsa to select instances from a filter and process them in the background, use [alteration plans](../alteration-plans/rest-api.md) instead.
+All endpoints on this page require the `run:alterations` permission.
+
For example, to apply an alteration that modifies a variable, migrates the workflow instance to a new version, and schedules an activity, use the following request:
```http
@@ -68,3 +70,39 @@ The response includes one result per targeted workflow instance:
```
After the runner finishes, the endpoint automatically dispatches any successful workflow instance that still has scheduled work.
+
+## Retry faulted activities
+
+`release/3.8.0` also exposes `POST /alterations/workflows/retry` for retrying faulted activities across one or more workflow instances.
+
+If you omit `activityIds`, Elsa retries all incident activity IDs recorded on each specified workflow instance.
+
+```http
+POST /alterations/workflows/retry HTTP/1.1
+Host: localhost:5001
+
+{
+ "workflowInstanceIds": [
+ "88ce68d00e824c78a53af04f16d276ea"
+ ]
+}
+```
+
+To retry only specific activities, include `activityIds`:
+
+```http
+POST /alterations/workflows/retry HTTP/1.1
+Host: localhost:5001
+
+{
+ "workflowInstanceIds": [
+ "88ce68d00e824c78a53af04f16d276ea"
+ ],
+ "activityIds": [
+ "ShipOrder",
+ "CapturePayment"
+ ]
+}
+```
+
+The response shape matches `/alterations/run` by returning one result per targeted workflow instance.