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

# Breaking Changes - Collaboration | Official Documentation

> The Collate 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/collatedocs/Uc6K6UUwOnvI7QWD/public/images/release-2.0/entity-activity-feeds-and-tasks.png?fit=max&auto=format&n=Uc6K6UUwOnvI7QWD&q=85&s=5e0ecc6419f82b183ea56d3c70124b35" alt="Collate 2.0 entity page showing the redesigned header and the Activity Feeds and Tasks tab" width="2200" height="1621" data-path="public/images/release-2.0/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`                                                |
| N/A                                     | `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`               | N/A      | Who can see events in this scope                 |
| `scope` / `scopeReference` | N/A      | 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 Collate 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>
