- name
- phoenix-release-notes
- description
- Create Phoenix release documentation grounded in actual code changes. Use this skill whenever the user asks to write release notes, document a release, update release documentation, or mentions undocumented releases. Also trigger when the user wants to update GitHub release descriptions, add entries to the release notes page, or asks what changed in a recent Phoenix version.
- metadata
- {"internal":true}
# Release Notes
Create and publish release documentation for Phoenix. This skill walks through a structured
workflow: identify undocumented releases, analyze commits by reading the actual code, draft MDX
files, and update all the documentation touchpoints.
## Tone and Style
Write for a developer who uses Phoenix daily. The voice is technical, friendly, and informative
without being verbose.
- **Active voice, present tense**: "Phoenix now provides..." not "A new feature has been added..."
- **Lead with what the user can do**, not what changed internally. The reader cares about
capabilities, not implementation details.
- **Most interesting first.** Order everything — page sections, the title, the intro, aggregate
bullets, the year card, the Slack overview — by reader interest, never by date, package, or the
order you discovered the commits. See "Rank features before writing" below.
- **Concise**: 1-2 sentence intro, then bullet points for details. If a bullet can say it, don't
write a paragraph. Stay inside the length budgets in Step 3.
- **Code examples are mandatory** when a feature has a programmatic API. Show working,
copy-pasteable snippets. Show both Python and TypeScript when both SDKs are affected.
- **Version requirements in bold**: `**Available in arize-phoenix X.Y.Z+**`
- **No PR numbers, commit hashes, or install commands** in the release notes themselves.
## Packages to Track
| Package | Tag pattern |
|---------|------------|
| arize-phoenix (server) | `arize-phoenix-v*` |
| arize-phoenix-client (Python SDK) | `arize-phoenix-client-v*` |
| arize-phoenix-evals | `arize-phoenix-evals-v*` |
| arize-phoenix-otel | `arize-phoenix-otel-v*` |
| @arizeai/phoenix-client (TS SDK) | Check `js/packages/phoenix-client/package.json` |
| @arizeai/phoenix-cli (TS CLI) | Check `js/packages/phoenix-cli/package.json` |
| @arizeai/phoenix-evals (TS evals) | Check `js/packages/phoenix-evals/package.json` |
| @arizeai/phoenix-mcp (TS MCP) | Check `js/packages/phoenix-mcp/package.json` |
| @arizeai/phoenix-otel (TS OTel) | Check `js/packages/phoenix-otel/package.json` |
## Step 1: Identify Undocumented Releases
Compare GitHub releases against existing documentation to find the gap.
```bash
# Recent GitHub releases
gh release list --repo Arize-ai/phoenix --limit 30
# Existing release note files
ls docs/phoenix/release-notes/*/
# Dates already covered in the aggregate file
grep 'ReleaseUpdate label=' docs/phoenix/release-notes.mdx
```
Each `<ReleaseUpdate>` entry in the aggregate file covers a date. Multiple versions released on the same
date get combined into one entry. Identify releases that have no corresponding coverage.
## Step 2: Analyze Commits
For each undocumented release, examine the actual changes — not just the commit messages.
### Get the changelog
```bash
gh release view <TAG> --repo Arize-ai/phoenix --json body --jq '.body'
```
The release body from release-please lists conventional commits with PR links. Use this as a
starting index, then dig deeper.
### Read the actual code
For each `feat()` and significant `fix()` commit, read the changed files to understand what the
feature actually does. Commit messages are often terse — the code tells the real story. Key places:
- **Server REST endpoints**: `src/phoenix/server/api/routers/v1/`
- **Python client SDK**: `packages/phoenix-client/src/phoenix/client/`
- **TypeScript client SDK**: `js/packages/phoenix-client/src/`
- **UI features**: `js/app/src/pages/`
- **Evaluators**: `packages/phoenix-evals/src/phoenix/evals/`
- **CLI**: `packages/phoenix-client/src/phoenix/client/cli/`
- **Models/providers**: playground and model configuration code
### Classify each change
**INCLUDE** — things users interact with directly:
- New API endpoints or SDK methods
- New UI features or pages
- New model or provider support
- Breaking changes to public APIs
- New CLI commands or flags
- New evaluator types or capabilities
- Performance improvements with visible user impact
**EXCLUDE** — internal housekeeping:
- Dependency bumps (`chore(deps):`, `fix(deps):`)
- Internal refactoring with no API surface change
- Test additions or fixes
- CI/CD and build changes
- Code style or formatting changes
- Internal tooling, repo-internal agent skills (`.agents/skills/`), or dev workflows with no
product behavior change
- Reverts that cancel out a feature within the same release
If a release contains only excluded changes, skip it — no release note needed.
### Group related commits
Multiple commits often implement a single feature across server + client + UI. A REST endpoint
commit, a Python client wrapper, and a TypeScript client wrapper should become one release note
entry that mentions all relevant package versions — not three separate entries.
### Rank features before writing
Sort the included changes into tiers **before** drafting. The page runs top to bottom in this
order, and the title, description, intro, aggregate bullets, year card, and Slack overview all lead
with whatever landed in the highest tier.
| Tier | What goes here | Examples |
|------|----------------|----------|
| 1 | New integrations, workflows, and evaluation capabilities that change how someone uses Phoenix | Harbor plugin, a new evaluator, PXI doing something new, a new UI surface |
| 2 | New model or provider support | Z.ai / MiniMax / Meta built in, new frontier models |
| 3 | SDK and CLI capabilities | new client methods or parameters, new `px` commands |
| 4 | Protocol, auth, and infrastructure changes | MCP server upgrades, OAuth changes, config variables |
| 5 | REST-only endpoints and administrative routes | `DELETE /v1/projects/{id}/traces`, retention policy CRUD |
| 6 | Fixes and small polish | `# Additional Improvements` |
Rules:
- **REST API changes always sit at the bottom**, immediately above `# Additional Improvements`.
Endpoint reference docs already cover them; the release note only needs to say they exist.
- **If a REST endpoint is also exposed through the SDKs, write it as an SDK feature.** Lead with
the client call, show SDK snippets, and mention the endpoint in one clause or a reference card.
Do not open the section with the HTTP verb and path.
- **Within a tier, bigger change first.** A feature with its own snippets and docs outranks a
one-bullet feature in the same tier.
- **Breaking changes are the exception**: a breaking change goes first regardless of tier.
- **A thin section drops a tier.** If a feature has less than a short paragraph of substance, it is
a bullet in `# Additional Improvements` or merged into a sibling section (for example, two small
PXI changes become one `# PXI: ...` section), not its own heading.
## Step 3: Draft MDX Files
### Default to a single consolidated file
**Prefer one release note over many.** Phoenix ships frequently, and a separate page per day
produces a noisy, hard-to-scan release feed. Before creating files, look at the whole batch of
undocumented releases together and ask: can these become **one** multi-topic file (Format B)?
Consolidate into a single file when the batch:
- Spans a short window (roughly a week or a handful of consecutive patch/minor versions), **or**
- Shares a theme (e.g. several time range, metrics, or PXI improvements), **or**
- Individually would produce thin pages (one or two features each).
Each feature inside the consolidated file keeps its own `# Heading`, date line, and
`**Available in arize-phoenix X.Y.Z+**` version line, so per-feature version provenance is
preserved even though they share one page. The frontmatter `title` and file are dated by the
**latest** release in the bundle, and the file `description` summarizes the whole bundle.
Only split into multiple files when a feature is genuinely large enough to deserve a standalone
page (a major launch, a breaking change, or a feature with substantial code examples and its own
media). When in doubt, consolidate — it is easier to read one well-organized page than five thin
ones.
If you are **revising** an existing batch that was already split into several thin files,
consolidate them: create one combined file dated by the latest release, delete the superseded
files (`git rm`), and collapse their entries down to a single `<ReleaseUpdate>` block and a single
year-overview `<Card>` and a single `docs.json` page path.
### Length budgets
Release notes are skimmed. Cut until each piece fits:
| Piece | Budget |
|-------|--------|
| Page intro | 1-2 sentences, leading with the tier-1 feature |
| Feature section | 1 short paragraph, 2-4 bullets, at most one snippet per language, one `<CardGroup>` |
| Bullet | 1-2 sentences. A bold lead plus one clause of detail |
| `# Additional Improvements` bullet | 1 sentence, bold lead, no sub-bullets |
| Whole page | Aim for under ~200 lines for a weekly bundle |
Cut first: restated reference material (parameter tables that exist in the API docs), a second
snippet that shows the same call with different values, `export FOO=...` blocks, and any sentence
that explains what the previous sentence already said.
### File location
```
docs/phoenix/release-notes/{MM-YYYY}/{MM-DD-YYYY}-{slug-title}.mdx
```
Create the month directory if it doesn't exist: `mkdir -p docs/phoenix/release-notes/MM-YYYY`
### Frontmatter title rules (apply to BOTH formats)
Every release note MDX file — single-topic or multi-topic — **must** have a descriptive,
date-prefixed `title` in its frontmatter. The title appears in browser tabs, the sidebar,
and search results, so a generic `"Release Notes"` makes the page indistinguishable from
the index page.
Required format: `title: "MM.DD.YYYY: Descriptive Title"`
- ✅ `title: "04.29.2026: Dataset Upsert"`
- ✅ `title: "05.05.2026: REST API Updates"`
- ✅ `title: "04.30.2026: Annotation Enhancements"`
- ❌ `title: "Release Notes"` — never use this; it collides with the index page
- ❌ `title: "Dataset Upsert"` — missing the date prefix
- ❌ `title: "04.29.2026 Dataset Upsert"` — missing the colon separator
For multi-topic files, the title summarizes the theme of the bundle (e.g.
`"04.30.2026: Annotation Enhancements"`), not any single feature inside it.
### Format A: Single-topic file
Use when one feature is significant enough to warrant its own page.
```mdx
---
title: "MM.DD.YYYY: Feature Title"
description: "One-sentence description of the feature."
---
Introductory paragraph explaining what users can now do.
## Section Heading
- **Bold lead** describing a capability
- **Another point** with technical detail
```python
# Working Python example
```
```ts
// Working TypeScript example
```
<CardGroup cols={2}>
<Card title="Related Doc" icon="book" href="/docs/phoenix/path">
Brief description
</Card>
</CardGroup>
```
### Format B: Multi-topic file
Use when several features from a date range are combined into one file. The frontmatter
`title` still follows the `MM.DD.YYYY: Theme` rule (see "Frontmatter title rules" above) —
**never** use `"Release Notes"`.
```mdx
---
title: "MM.DD.YYYY: Theme Title"
---
# Feature Title One
Month DD, YYYY
**Available in arize-phoenix X.Y.Z+**
Description paragraph.
- **Bullet** describing capability
```python
# code example
```
# Feature Title Two
Month DD, YYYY
**Available in package-name X.Y.Z+**
Description paragraph.
```
### Version line format
Match the version line to which packages are involved:
```
**Available in arize-phoenix 13.14.0+**
**Available in arize-phoenix-client 2.0.0+ (Python) and @arizeai/phoenix-client 6.4.0+ (TypeScript)**
**Available in arize-phoenix 13.13.0+ (server), arize-phoenix-client 1.31.0+ (Python)**
**Available in arize-phoenix 15.1.0+ (beta)**
**Breaking change in arize-phoenix-client 2.0.0**
```
### Choosing between formats
| Situation | Format |
|-----------|--------|
| Multiple features across a short window or shared theme | **Format B — one consolidated file (default)** |
| A single, genuinely major feature or breaking change worth its own page | Format A |
| Feature spans server + client | One entry, mention all package versions |
| Breaking change | Prefix title with "Breaking Change:" |
| TS-only or Python-only feature | Show only the relevant language |
| Video/screenshot available | Use `<video>` or `<Frame>` in the relevant section of the file |
## Step 4: Update the Aggregate File
File: `docs/phoenix/release-notes.mdx`
Insert each new `<ReleaseUpdate>` block at the correct chronological position relative to **all**
existing blocks — not as a contiguous group at the top. Each block is a condensed summary
linking to the individual file.
The file imports the `ReleaseUpdate` component at the top (after the frontmatter):
```mdx
import { ReleaseUpdate } from "../snippets/ReleaseUpdate.jsx";
```
```mdx
<ReleaseUpdate label="MM.DD.YYYY" href="/docs/phoenix/release-notes/MM-YYYY/MM-DD-YYYY-slug-title" title="Feature Title">
**Available in ...**
Brief 1-3 sentence summary. Action-oriented.
- **Key capability** with brief description
- **Another capability** with brief description
</ReleaseUpdate>
```
Rules:
- `label` uses dot separators: `MM.DD.YYYY`
- `title` is the feature title (without date prefix — the component generates `label: title` as the heading)
- `href` is the link to the individual MDX file
- Link path has no `.mdx` extension
- Keep each block to 5-10 lines: one version line, a 1-2 sentence summary, and **at most 6
bullets of one line each**, in the ranked order from "Rank features before writing" — the first
bullet is the headline feature, REST-only changes are last
- For a consolidated multi-topic file, prefer a **single** `<ReleaseUpdate>` block labeled with the
latest date, whose bullets summarize the bundled features — one block per file, not one per
feature. Only split into multiple blocks when the bundled features fall on clearly distinct dates
that each merit their own line in the feed.
### Reverse-chronological insertion (do not skip this)
The aggregate file is sorted strictly newest-first by date. Existing entries are already
ordered, so inserting a batch of new entries is a **merge**, not an append.
**Wrong** — stacking all new entries at the top as a contiguous block:
```
[NEW 05.05] [NEW 05.05] [NEW 04.30] [NEW 04.30] [NEW 04.29] [old 05.01] [old 04.28] ...
^^^^^^^^^^
older date appears AFTER newer dates — broken
```
**Right** — interleave each new entry with existing entries by date:
```
[NEW 05.05] [NEW 05.05] [old 05.01] [NEW 04.30] [NEW 04.30] [NEW 04.29] [old 04.28] ...
```
Procedure when adding multiple entries:
1. List every date you are adding.
2. Read the existing labels in order: `grep -n 'Update label=' docs/phoenix/release-notes.mdx`
3. For **each** new entry, find the first existing label whose date is strictly older, and
insert the new block immediately before it. Same-date ties stay together.
4. After inserting, re-run the grep and read the dates top-to-bottom — they must be
monotonically non-increasing. If any older date appears above a newer one, fix it
before moving on.
## Step 5: Update the Year Overview
File: `docs/phoenix/release-notes/YYYY.mdx` (e.g., `2026.mdx`)
Add a `<Card>` entry at the top of the `<CardGroup>`:
```mdx
<Card href="/docs/phoenix/release-notes/MM-YYYY/MM-DD-YYYY-slug-title" arrow="true" title="MM.DD.YYYY" icon="calendar" description="Brief description of the feature"/>
```
Voir sur GitHub