# Release Notes & Digests

Hand-written release notes are late, incomplete or written for the wrong reader; Bumpkit writes them from what it proved, for product, support and developer-relations teams.

> **Beta, early access.** A workspace without access gets `403 FEATURE_EARLY_ACCESS` and a link to request it. Flag: `release_docs`.

Bumpkit writes release documentation from a [release check](/docs/release-checks): what the commits say and what Bumpkit proved in the code. You view it, publish it where your team and customers read it, and, with the newer features, tailor it per audience and send a weekly digest.

| Feature | Flag |
|---------|------|
| [Release docs](#release-docs) and [publishing](#publish-release-docs) | `release_docs` |
| [Notes per audience](#notes-per-audience) | `audience_notes` |
| [Consumer migration guide](#consumer-migration-guide) | `consumer_migration_guide` |
| [Weekly digest](#weekly-digest) | `weekly_digest` |
| [Notion and Confluence](#notion-and-confluence) | `notion_confluence` |

## Release docs

Every checked release has three parts:

| Part | What it contains |
|------|------------------|
| Engineering notes | The release's changelog, or the check summary if there is none |
| Customer notes | The changelog rewritten for people who use the product, grouped under New, Improved and Fixed, with internal work left out. Without a configured model, the changelog with commit links removed |
| Migration guide | Proven findings grouped as Breaking changes (high-severity breaks), Database (migrations and data loss), Configuration (new settings) and Dependencies. Empty when there is nothing to migrate |

Docs are generated on first request and saved. Use `--regenerate` after the release changed.

```bash
bumpkit docs view 1f6d3c2a-...
bumpkit docs view 1f6d3c2a-... --part migration
bumpkit docs view 1f6d3c2a-... --regenerate
```

`--part` is `engineering`, `customer` or `migration`. The check ID comes from `bumpkit check`, `bumpkit checks list` or the gate output.

The API is `GET /v1/checks/{id}/docs`, with `?regenerate=true` to write them again. Agents use the `release_docs` [MCP tool](/docs/mcp) with `check_id` and `regenerate`.

## Publish release docs

```bash
bumpkit docs publish 1f6d3c2a-... --to changelog,github_release,slack
```

| Target | What is published | Needs |
|--------|-------------------|-------|
| `changelog` | Customer notes plus the migration guide, as this version on your [public changelog page](/docs/changelog-pages) | Nothing; the page shows it when public |
| `github_release` | A GitHub Release tagged `v<version>` with the engineering notes plus the migration guide | The [Bumpkit GitHub App](/docs/#install-the-github-app) installed on the repository and linked to your workspace |
| `slack` | Customer notes plus the migration guide | [Slack](/docs/slack) connected |
| `discord` | Customer notes plus the migration guide | [Discord](/docs/discord) connected |
| `notion`, `confluence` | See [Notion and Confluence](#notion-and-confluence) | Beta, a doc connection |

The release must have a version, so check it against a previous version tag first. Each successful publication is recorded with its URL and who published it, and shows in the docs' `publications`. If some targets fail, the others still publish and the response is `502 PUBLISH_FAILED` listing each failure.

The API is `POST /v1/checks/{id}/publish` with `{"targets": ["changelog", "slack"]}`. Add `"audience": "customer"` to publish that audience's [notes](#notes-per-audience) to every target instead. Agents use the `publish_release` MCP tool with `check_id`, `targets` and an optional `audience`. [Grouped releases](/docs/release-trains#grouped-releases) always publish each target with its own audience: the customer notes to the changelog and GitHub Release, the engineering notes to Slack, Notion and Confluence. You can also publish from the release decision page on the dashboard.

## Correct published notes

Published notes can still be wrong, like an internal-only line that reached the public changelog. Owners and admins can correct them after the fact:

```bash
bumpkit release correct RELEASE_ID --audience customer --file notes.md --reason "Remove internal-only lines"
```

This replaces the stored notes for that audience and updates every place they were published: the [public changelog](/docs/changelog-pages) entry and its RSS feed, the GitHub Release body (through the Bumpkit GitHub App), and any Notion or Confluence page. Messages already posted to Slack aren't edited; the output says so, so you can post a follow-up. Each target reports `updated` or `failed` on its own. Run the same command again to retry a target that failed; it exits `1` while one still fails. The changelog keeps the entry's date and order and doesn't mark it as edited.

For an older changelog entry that wasn't a grouped release, name it by version:

```bash
bumpkit release correct --version v1.2.0 --repo acme/api --file entry.md --reason "Remove an internal-only line"
```

`--repo` defaults to the repository your public changelog shows. Only the changelog entry changes on this path.

`--reason` is required and needs at least 10 characters. Every correction goes in the [audit log](/docs/compliance#audit-log) as `release.notes.correct` or `changelog.correct`, with who made it, the release, the reason and SHA-256 hashes of the notes before and after. Read the current notes first with `bumpkit release show RELEASE_ID --audience customer`.

On the dashboard, open the published release, pick the audience's tab and use **Correct published notes**. Agents use the `correct_release_notes` MCP tool. The API is `POST /v1/releases/{id}/corrections` with `{"audience": "customer", "body": "...", "reason": "..."}`, or `POST /v1/changelog/corrections` with `{"version": "v1.2.0", "repository": "acme/api", "body": "...", "reason": "..."}`.

## Notes per audience

> **Beta, early access.** A workspace without access gets `403 FEATURE_EARLY_ACCESS` and a link to request it. Flag: `audience_notes`.

Notes per audience are built only from the release's changelog items and proven findings, and each item links to its source: the commit, pull request, file and line, or the compare view.

```bash
bumpkit docs notes 1f6d3c2a-... --audience support
bumpkit docs notes 1f6d3c2a-... --audience customer --segment enterprise
```

`--audience` defaults to `customer`. `--regenerate` writes the notes again. The API is `GET /v1/checks/{id}/notes?audience=&segment=&regenerate=true`, and the MCP tool is `release_notes` (`check_id`, `audience`, `segment`, `regenerate`).

Customer notes keep only what a customer can see or do: new features, fixes they'd notice and changes in behavior. Items about internal-only work go to the `Internal` section, which the customer, support and leadership audiences leave out: internal tooling, tests and test infrastructure such as test databases and fixtures, docs-internal changes like docs tests and removed redirects, drafts like a draft privacy policy, unreleased or not-yet-public work, how detection works internally, and internal process like refactors and CI.

When the workspace's retention mode allows it, Bumpkit writes the items in the audience's tone; `generator` in the response says whether AI wrote them (`llm`) or not (`deterministic`). Hidden paths stay hidden either way.

### Audiences

Five audiences are built in. You can override any of them or add your own.

| Key | Sections | Hides paths |
|-----|----------|-------------|
| `engineering` | All sections | no |
| `customer` | breaking, new, improved, fixed | yes |
| `support` | breaking, new, fixed, improved, config, risk | yes |
| `security` | security, breaking, config, dependencies, database, risk | no |
| `leadership` | breaking, new, improved, fixed, security, risk | yes |

`customer`, `support` and `leadership` also exclude `internal/**`, `test/**`, `tests/**`, `**/*_test.*`, `**/*.test.*`, `.github/**`, `ci/**` and `scripts/**`.

Sections are `breaking`, `new`, `improved`, `fixed`, `security`, `database`, `config`, `dependencies`, `risk` and `internal`. Changelog items go to a section by their heading; findings by kind (for example secrets and vulnerable dependencies go to `security`, migrations to `database`).

Owners and admins save an audience with `PUT /v1/release-notes/audiences/{key}`:

```json
{
  "name": "Partners",
  "tone": "Short and direct, for integration partners.",
  "sections": ["breaking", "new", "config"],
  "exclude": ["admin/**", "web/**"],
  "hide_paths": true
}
```

| Field | Rules |
|-------|-------|
| `{key}` | Lowercase letters, digits, `-` or `_`, starting with a letter, up to 32 characters |
| `name` | Required, up to 80 characters |
| `tone` | Up to 500 characters |
| `sections` | At least one |
| `exclude` | Up to 50 path globs; matching items are dropped and matching paths are replaced with "a file" |
| `hide_paths` | Replace every file path with "a file" and link to the compare view instead |

`DELETE /v1/release-notes/audiences/{key}` removes a custom audience or restores a built-in one.

### Features and segments

Tag features so Bumpkit knows which changes belong to them, then define customer segments by the features they use. Notes for a segment drop items tagged only with features the segment doesn't use; untagged items stay.

```bash
curl -X PUT https://bumpkit.dev/v1/release-notes/features/billing \
  -H "x-api-key: $BUMPKIT_API_KEY" -H "Content-Type: application/json" \
  -d '{"paths": ["billing/**"], "keywords": ["invoice"]}'

curl -X PUT https://bumpkit.dev/v1/release-notes/segments/enterprise \
  -H "x-api-key: $BUMPKIT_API_KEY" -H "Content-Type: application/json" \
  -d '{"name": "Enterprise customers", "plan": "Enterprise", "features": ["billing", "sso"]}'
```

| Object | Fields |
|--------|--------|
| Feature (`/v1/release-notes/features/{name}`) | Name up to 64 letters, numbers, spaces, dots, dashes or underscores, starting with a letter or number; `paths` and `keywords`, up to 50 each, at least one |
| Segment (`/v1/release-notes/segments/{key}`) | Key as for audiences; `name` up to 80 characters; `plan` up to 64; `features` |

`GET /v1/release-notes/config` returns all audiences, segments and features (MCP tool `release_audiences`). Writes need an owner or admin and are written to the audit log. You can also manage them on the **Release notes** tab of the dashboard's Releases page.

## Consumer migration guide

> **Beta, early access.** A workspace without access gets `403 FEATURE_EARLY_ACCESS` and a link to request it. Flag: `consumer_migration_guide`.

For a breaking release, Bumpkit writes a what-to-change guide for the people who consume your code, one step per proven break, with before and after lines from the diff and a link to the source.

```bash
bumpkit docs guide 1f6d3c2a-...
```

| Proven change | Step |
|---------------|------|
| Removed public API | Stop using it |
| Changed signature | Update calls, with the old and new signature |
| Removed route | Stop calling the endpoint |
| Other breaking or contract change | Review it before upgrading |
| New environment variable | Set it in every environment |
| Data migration or data loss | Back up and plan the rollout |
| Major dependency upgrade | Check its changelog |

A release counts as breaking when its bump is major, or it has a proven high-severity break or a contract break. Otherwise `breaking` is `false` and there are no steps. The API is `GET /v1/checks/{id}/consumer-guide`; the MCP tool is `consumer_migration_guide` (`check_id`).

## Weekly digest

> **Beta, early access.** A workspace without access gets `403 FEATURE_EARLY_ACCESS` and a link to request it. Flag: `weekly_digest`.

A digest covers one repository's last seven days, ending when it's sent. It opens with a one-sentence headline and four numbers (shipped, ready, held, blocked, with the change from the week before), then lists up to five pull requests that need attention with the reason and an **Open in Bumpkit** button, up to five ready but not deployed, who wrote the changes (agents by name, or *No AI-agent signals*), and proven high-severity findings when there are any. Each pull request appears once, with its latest decision. Empty sections are left out.

A scheduled digest sends once per scheduled time, and skips the week when nothing was checked. **Send now** says where each copy went, like `Sent to #releases in Slack at 9:28 AM MDT`, with a link to the Slack message when Bumpkit's Slack app posted it. If no destination is connected, nothing is sent and the reply says what to connect.

```bash
bumpkit digest set acme/api --day mon --time 09:00 --timezone America/New_York --to slack,email --email lead@acme.dev
bumpkit digest list
bumpkit digest preview 5c1d...
bumpkit digest send 5c1d...
bumpkit digest delete 5c1d...
```

| Flag (`digest set`) | Default | Meaning |
|---------------------|---------|---------|
| `--day` | `mon` | `sun` to `sat` |
| `--time` | `09:00` | Time of day, `HH:MM` |
| `--timezone` | `UTC` | An IANA name, like `America/New_York` |
| `--to` | none | `slack`, `discord`, `email` |
| `--email` | none | Addresses for the `email` target, up to 20 |
| `--paused` | off | Save the schedule without sending |

Running `digest set` again for the same repository changes its schedule. Slack and Discord need their [integrations](/docs/integrations) connected.

| Endpoint | Purpose |
|----------|---------|
| `GET /v1/digests` | List schedules with `next_run_at` and `last_sent_at` |
| `PUT /v1/digests` | Create or change one: `repository`, `timezone`, `weekday` (0 is Sunday), `hour`, `minute`, `targets`, `emails`, `enabled` |
| `GET /v1/digests/{id}/preview` | The digest as it would be sent now |
| `POST /v1/digests/{id}/send` | Send it now; `deliveries` lists each destination, time and message link |
| `DELETE /v1/digests/{id}` | Delete a schedule |

Changing, sending and deleting need an owner or admin. The MCP tool `weekly_digests` lists schedules.

## Notion and Confluence

> **Beta, early access.** A workspace without access gets `403 FEATURE_EARLY_ACCESS` and a link to request it. Flag: `notion_confluence`.

Publish release docs as a Notion page or a Confluence page. The page holds the customer notes, migration guide and engineering notes, and is titled `<repository> v<version>`. Publishing the same release again updates the same page.

### Connect

Notion: create an internal integration, share the parent page with it, then:

```bash
bumpkit docs connect notion --token-env NOTION_TOKEN --parent https://www.notion.so/acme/Releases-1a2b3c...
```

Confluence Cloud, with an Atlassian API token:

```bash
bumpkit docs connect confluence --site https://acme.atlassian.net --email you@acme.dev \
  --token-env CONFLUENCE_TOKEN --parent ENG --parent-page 123456
```

| Flag | Meaning |
|------|---------|
| `--token-env` | The environment variable that holds the Notion integration token, Confluence API token or personal access token. `--token-file` reads it from a private file and `--token-stdin` from stdin |
| `--parent` | Notion parent page link, or Confluence space key |
| `--site` | Confluence site address |
| `--email` | Atlassian account email, for Confluence Cloud API tokens (omit it for a personal access token) |
| `--parent-page` | Confluence parent page id, the number in the page's URL |

Bumpkit checks the token against the page or space before saving it, and stores it encrypted. On the dashboard's Integrations page you can also sign in with Notion or Atlassian instead of pasting a token.

```bash
bumpkit docs connections
bumpkit docs disconnect confluence
bumpkit docs publish 1f6d3c2a-... --to notion,confluence
```

The API is `GET /v1/doc-connections`, `PUT /v1/doc-connections/{provider}` (`token`, `parent`, `base_url`, `email`, `parent_page`) and `DELETE /v1/doc-connections/{provider}`, where `{provider}` is `notion` or `confluence`. Connecting and disconnecting need an owner or admin.

See the [CLI Reference](/docs/cli) and [API Reference](/docs/api-reference) for every flag and field.
