> ## Documentation Index
> Fetch the complete documentation index at: https://docs.open-metadata.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Breaking Changes - Collaboration | Official Documentation

> The OpenMetadata 2.0 Task redesign, removal of the Suggestions API, standalone Announcements, the ephemeral Activity Stream and alert filter changes.

# Collaboration: Tasks, Suggestions, Announcements & Feed

2.0 retires the thread-backed collaboration model. Tasks, suggestions, announcements and system
activity each move out of `thread_entity` into purpose-built entities with their own tables, APIs and
permissions. Human conversations remain on `/v1/feed`.

| Concern         | 1.13 storage                          | 2.0 storage                                            |
| --------------- | ------------------------------------- | ------------------------------------------------------ |
| Conversations   | `thread_entity`                       | `thread_entity` (unchanged)                            |
| Tasks           | `thread_entity` (`type=Task`)         | **`task_entity`**                                      |
| Suggestions     | `suggestions` table                   | **`task_entity`** (`type=Suggestion`)                  |
| Announcements   | `thread_entity` (`type=Announcement`) | **`announcement_entity`**                              |
| System activity | `thread_entity` generated rows        | **`activity_stream`** (partitioned, retention-bounded) |

<img src="https://mintcdn.com/openmetadata/5hfq1BU_b0iSOkqa/public/images/deployment/upgrade/breaking-changes/entity-activity-feeds-and-tasks.png?fit=max&auto=format&n=5hfq1BU_b0iSOkqa&q=85&s=6037a6d52b54c4b80217ab2bce4e455a" alt="OpenMetadata 2.0 entity page showing the redesigned header and the Activity Feeds and Tasks tab" width="2200" height="1621" data-path="public/images/deployment/upgrade/breaking-changes/entity-activity-feeds-and-tasks.png" />

## The Task redesign

<Warning>
  **Breaking.** Affects API clients, bots and workflow integrations reading `/v1/feed/tasks/*`.
</Warning>

Tasks are now a first-class entity backed by `task_entity`, with a full CRUD and versioning surface at
`/v1/tasks` — 22 new endpoints:

| Endpoint                                                             | Purpose                          |
| -------------------------------------------------------------------- | -------------------------------- |
| `GET` / `POST` / `PUT` `/v1/tasks`                                   | List, create, upsert             |
| `GET /v1/tasks/{id}`, `GET /v1/tasks/name/{taskId}`                  | Fetch by UUID or human task id   |
| `PATCH /v1/tasks/{id}`, `DELETE /v1/tasks/{id}`                      | Update, delete                   |
| `POST /v1/tasks/{id}/resolve`, `POST /v1/tasks/{id}/close`           | Lifecycle transitions            |
| `PUT /v1/tasks/{id}/suggestion/apply`                                | Apply a suggestion payload       |
| `POST /v1/tasks/{id}/comments`, `PATCH` / `DELETE` `.../{commentId}` | Threaded comments                |
| `GET /v1/tasks/assigned`, `/created`, `/owned`, `/visible`           | Scoped task lists                |
| `GET /v1/tasks/count`, `GET /v1/tasks/dataAccessRequests`            | Counts and the data-access queue |
| `POST /v1/tasks/bulk`                                                | Bulk operations                  |
| `GET /v1/tasks/{id}/versions[/{version}]`                            | Entity version history           |

### The Task shape

```json theme={null}
{
  "taskId": "TASK-1042",
  "category": "Approval",
  "type": "GlossaryApproval",
  "status": "Open",
  "priority": "Medium",
  "about": { "type": "glossaryTerm", "id": "..." },
  "assignees": [], "reviewers": [], "watchers": [],
  "payload": { },
  "resolution": { },
  "dueDate": 1712345678000,
  "workflowInstanceId": "...", "workflowStageId": "...",
  "availableTransitions": [],
  "taskFormSchemaId": "...", "taskFormSchemaVersion": 0.1,
  "comments": [], "commentCount": 0,
  "domains": [], "tags": [], "externalReference": { }
}
```

Required fields: `id`, `name`, `category`, `type`, `status`, `createdBy`.

| Enum             | Values                                                                                                                                                                                                                                                                                     |
| ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `taskCategory`   | `Approval`, `DataAccess`, `MetadataUpdate`, `Incident`, `Review`, `Custom`                                                                                                                                                                                                                 |
| `taskType`       | `GlossaryApproval`, `RequestApproval`, `DataAccessRequest`, `DescriptionUpdate`, `TagUpdate`, `OwnershipUpdate`, `TierUpdate`, `DomainUpdate`, `Suggestion`, `TestCaseResolution`, `IncidentResolution`, `PipelineReview`, `DataQualityReview`, `RecognizerFeedbackApproval`, `CustomTask` |
| `taskStatus`     | `Open`, `InProgress`, `Pending`, `Approved`, `Granted`, `ManualRevoke`, `Rejected`, `Completed`, `Cancelled`, `Failed`, `Revoked`, `Expired`                                                                                                                                               |
| `taskPriority`   | `Critical`, `High`, `Medium`, `Low`                                                                                                                                                                                                                                                        |
| `resolutionType` | `Approved`, `Rejected`, `Completed`, `Cancelled`, `TimedOut`, `AutoApproved`, `AutoRejected`, `Revoked`, `Expired`                                                                                                                                                                         |

Typed payload schemas ship for each task type: `glossaryApprovalPayload`, `descriptionUpdatePayload`,
`tagUpdatePayload`, `ownershipUpdatePayload`, `tierUpdatePayload`, `domainUpdatePayload`,
`suggestionPayload`, `reviewPayload`, `testCaseResolutionPayload`, `incidentResolutionPayload`,
`dataAccessRequestPayload` and `genericTaskPayload`.

### Migration

The migration converts every `thread_entity` row with `type='Task'` into a Task, computing `about` and
`aboutFqnHash` from the entity link. A `task_migration_mapping` table records
`old_thread_id → new_task_id` for traceability and redirects.

### `/v1/feed` task creation is now restricted

<Warning>
  **Breaking.**
</Warning>

`/v1/feed` still exposes `GET /v1/feed/tasks/{id}`, `PUT /v1/feed/tasks/{id}/resolve` and
`PUT /v1/feed/tasks/{id}/close`, but creating a task thread through `POST /v1/feed` now validates the
task type and rejects anything outside the supported legacy set — description, tag, approval and
test-case-failure-resolution tasks.

Additional validations on `POST /v1/feed`:

* `about` is required and must be non-blank.
* `taskDetails` is required for `Task` threads and **forbidden** on non-task threads.
* `RequestApproval` tasks must target an entity, not a field or column.
* Tag-task `oldValue` and `suggestion` must be valid tag-label JSON.

<Tip>
  Move task creation to `POST /v1/tasks`. If you must stay on `/v1/feed`, restrict yourself to the four
  supported legacy task types and supply well-formed `taskDetails`.
</Tip>

### New task permissions

<Note>
  **Behavioural.** Affects non-admin users and application bots.
</Note>

Five new policy operations exist in 2.0: `CreateTask`, `EditTask`, `ResolveTask`, `CloseTask` and
`ReassignTask`. The migration backfills them so existing tenants keep working:

| Migration step                                 | Effect                                                              |
| ---------------------------------------------- | ------------------------------------------------------------------- |
| `addTaskAuthorPolicyToDataConsumerRole`        | Seeds `TaskAuthorPolicy` and attaches it to the `DataConsumer` role |
| `addCreateTaskRuleToDataConsumerPolicy`        | Adds `DataConsumerPolicy-CreateTask-Rule`                           |
| `addTaskRuleToDataConsumerPolicy`              | Adds the per-entity `CreateTask`/`EditTask` grant                   |
| `addCreateTaskOperationToApplicationBotPolicy` | Lets application bots file suggestions as tasks                     |

<Warning>
  Custom policies are **not** backfilled. Seed policies are create-if-not-exists, so if you replaced
  `DataConsumerPolicy` or `ApplicationBotPolicy` with your own definition, add the task operations
  yourself or non-admin users will get `403` when filing or patching tasks.
</Warning>

Task authorization is also **self-approval guarded** — a task's creator cannot approve their own task.

## Suggestions become Tasks

<Warning>
  **Breaking.** Affects AI and automation bots and SDK users.
</Warning>

| 1.13                                            | 2.0                                                       |
| ----------------------------------------------- | --------------------------------------------------------- |
| `GET /v1/suggestions?entityFQN=…`               | `GET /v1/tasks?…` filtered on `type=Suggestion`           |
| `POST /v1/suggestions`                          | `POST /v1/tasks` with `type: Suggestion`                  |
| `PUT /v1/suggestions/{id}/accept`               | `PUT /v1/tasks/{id}/suggestion/apply`, then resolve       |
| `PUT /v1/suggestions/{id}/reject`               | `POST /v1/tasks/{id}/resolve` with a rejecting resolution |
| `PUT /v1/suggestions/accept-all` / `reject-all` | `POST /v1/tasks/bulk`                                     |

Status mapping:

| Task status                       | Suggestion status |
| --------------------------------- | ----------------- |
| `Open`, `InProgress`, `Pending`   | `Open`            |
| `Completed`, `Approved`           | `Accepted`        |
| `Rejected`, `Cancelled`, `Failed` | `Rejected`        |

The suggestion field path moves from an entity link to `payload.fieldPath` in dot notation
(`columns.col_name.description`).

## Announcements are a standalone entity

<Warning>
  **Breaking.** Affects anything reading or writing announcements through the feed API.
</Warning>

`/v1/feed` now rejects announcements outright with:

```
Announcements are no longer served from /v1/feed. Use /v1/announcements instead.
```

The guard fires on list (`threadType=Announcement`), get-by-id, patch, create, delete, posts and
reactions — any request touching an announcement thread returns `400`.

```
GET/POST/PUT   /v1/announcements
GET            /v1/announcements/{id}
GET            /v1/announcements/name/{fqn}
PATCH          /v1/announcements/{id}
DELETE         /v1/announcements/{id}
PUT            /v1/announcements/restore
GET            /v1/announcements/{id}/versions[/{version}]
```

### Migration shape

| Thread field                            | Announcement field                                  |
| --------------------------------------- | --------------------------------------------------- |
| `id`                                    | `id`                                                |
| —                                       | `name` / `fullyQualifiedName` = `announcement-<id>` |
| `message`                               | `displayName`                                       |
| `announcement.description` ?? `message` | `description`                                       |
| `about`                                 | `entityLink`                                        |
| `announcement.startTime` / `endTime`    | `startTime` / `endTime`                             |
| derived from times                      | `status` = `Active` \| `Scheduled` \| `Expired`     |
| `threadTs`                              | `createdAt`                                         |
| `reactions`                             | `reactions`                                         |

Announcements are full entities in 2.0 — versioned, soft-deletable and restorable — and the UI renders
them in the entity header rather than only in the feed widget.

## The Activity Stream replaces system-generated feed threads

<Warning>
  **Breaking.** Affects anything treating the feed as an audit trail.
</Warning>

System-generated activity (field changes, entity created/updated) no longer lives in `thread_entity`.
It moves to a purpose-built, time-partitioned, retention-bounded `activity_stream` table with its own
API:

| Endpoint                                                     | Purpose                            |
| ------------------------------------------------------------ | ---------------------------------- |
| `GET /v1/activity`                                           | Global stream                      |
| `GET /v1/activity/my-feed`                                   | Current user's feed                |
| `GET /v1/activity/following`                                 | Followed entities                  |
| `GET /v1/activity/user/{userId}`                             | A user's activity                  |
| `GET /v1/activity/entity/{entityType}/{entityId}`            | Per entity                         |
| `GET /v1/activity/entity/{entityType}/name/{fqn}`            | Per entity by fully qualified name |
| `GET /v1/activity/about`                                     | By entity link                     |
| `GET /v1/activity/count`                                     | Count                              |
| `PUT` / `DELETE` `/v1/activity/{id}/reaction/{reactionType}` | Reactions                          |

### Activity is deleted after 30 days by default

<Warning>
  **Behavioural — data loss on old activity.**
</Warning>

`activityStreamConfig` is configurable globally or per domain:

| Field                      | Default  | Meaning                                          |
| -------------------------- | -------- | ------------------------------------------------ |
| `enabled`                  | `true`   | Generate activity events for this scope          |
| `retentionDays`            | **`30`** | Events older than this are deleted automatically |
| `excludeEventTypes`        | `[]`     | Event types to skip                              |
| `excludeEntityTypes`       | `[]`     | Entity types to skip                             |
| `visibility`               | —        | Who can see events in this scope                 |
| `scope` / `scopeReference` | —        | Global or per domain                             |

Events carry `domains` inherited from the source entity, enabling domain-scoped feed visibility.
`oldValue` and `newValue` are explicitly documented as *"truncated for display, not for audit"*.

<Warning>
  Do not use the activity stream as an audit trail. For compliance history use **entity version
  history** (`/v1/{entityType}/{id}/versions`) and the **audit log** (`/v1/audit/logs`, which gains a
  searchable `search_text` column and an export endpoint in 2.0). Activity events are ephemeral by
  design.
</Warning>

## `thread_entity` is renamed

<Note>
  **Behavioural.** Affects anyone querying the OpenMetadata database directly.
</Note>

```sql theme={null}
-- 2.0.0 post-data migration
RENAME TABLE thread_entity TO thread_entity_legacy;              -- MySQL
ALTER TABLE IF EXISTS thread_entity RENAME TO thread_entity_legacy;  -- Postgres
```

The feed repository resolves the legacy table dynamically, so migrated threads stay readable.

<Tip>
  Update any BI dashboards, retention jobs or support scripts that query `thread_entity` directly.
</Tip>

## Task Form Schemas

<Info>
  **Additive.**
</Info>

`/v1/taskFormSchemas` stores per-task-type form definitions, referenced from a Task via
`taskFormSchemaId` and `taskFormSchemaVersion`. This is what lets governance workflows render custom
task forms.

## Change events for tasks and lineage

<Info>
  **Additive.** Affects webhook and event-subscription consumers.
</Info>

`changeEventType` adds `taskCreated`, `taskUpdated`, `entityLineageAdded`, `entityLineageDeleted` and
`entityLineageUpdated`. `changeEvent` adds a `recursive` flag marking cascade deletes — a single event
is recorded for the deleted root, and cascaded descendants produce no individual events.

<Tip>
  Consumers that previously counted per-child delete events must read `recursive` instead.
</Tip>

## Alert and notification behaviour changes

<Warning>
  **Behavioural.** Affects existing alert subscriptions.
</Warning>

### Thread events are scoped by their parent entity

In 1.13, the entity-FQN filter returned `true` unconditionally for thread change events — thread
activity bypassed the filter entirely. In 2.0 a thread event is matched against the fully qualified
name of the entity the thread is **about**.

An alert scoped to `service.db.schema` that previously fired for *every* conversation and task in the
system now fires only for threads about entities under that name. Alerts that looked noisy will go
quiet; alerts you relied on for global thread coverage will stop firing.

### Filter matching is literal, not regular-expression

Alert filter functions now match fully qualified names **literally**. Descendant matching is handled
explicitly. An alert whose filter used regular-expression metacharacters (`.`, `*`, `|`) to match a
family of names no longer matches — enumerate the names or rely on descendant matching.

### Other alert changes

| Change                                                                 | Effect                                          |
| ---------------------------------------------------------------------- | ----------------------------------------------- |
| Observability status triggers no longer fire on thread events          | Fewer spurious observability alerts             |
| Owner and user name filters match usernames containing a dot           | Previously-missed recipients now match          |
| `testDestination` redacts destination config in the response           | Secrets are no longer echoed back               |
| Filter expressions compiled once, combined condition validated at save | Invalid filters fail at save, not at fire time  |
| Recipients without contact info are skipped                            | Partial delivery instead of total batch failure |
| Incident-task comment mentions and assignee alerts rewired             | Mentions work again after the task migration    |

<Tip>
  Audit every alert with an entity name filter after upgrading, and test with
  `POST /v1/events/subscriptions/testDestination`.
</Tip>

## Server-side feed and task time filters

<Info>
  **Additive.** Both the feed list and task list APIs accept `startTs` and `endTs` for server-side
  time-range filtering, replacing client-side windowing.
</Info>
