diff --git a/docs/docs.json b/docs/docs.json
index 1221beb2..ede4060b 100644
--- a/docs/docs.json
+++ b/docs/docs.json
@@ -192,7 +192,8 @@
"rfds/custom-llm-endpoint",
"rfds/plan-operations",
"rfds/tool-call-name",
- "rfds/get-auth-state"
+ "rfds/get-auth-state",
+ "rfds/session-compaction"
]
},
{
diff --git a/docs/rfds/session-compaction.mdx b/docs/rfds/session-compaction.mdx
new file mode 100644
index 00000000..d6822166
--- /dev/null
+++ b/docs/rfds/session-compaction.mdx
@@ -0,0 +1,280 @@
+---
+title: "Session Compaction"
+---
+
+Author(s): [@benbrandt](https://github.com/benbrandt)
+
+## Elevator pitch
+
+> What are you proposing to change?
+
+Add ID-addressed `compaction_update` and `compaction_summary_chunk` session
+updates to ACP v1 and v2. Agents can report when context compaction starts,
+update that same timeline entity when it finishes, and optionally stream or
+materialize the user-displayable summary retained by the compaction.
+
+## Status quo
+
+> How do things work today and what problems does this cause? Why would we change things?
+
+ACP can report current context-window utilization through `usage_update`, but
+it cannot report that an Agent is compacting its context or preserve the
+resulting boundary in session history.
+
+Agents currently have to omit compaction, use an implementation-specific
+update, or describe it through an ordinary agent message. An agent message is
+the wrong semantic shape.
+
+Agent runtimes also expose different amounts of compaction information. Some
+provide a stable lifecycle item and a user-displayable summary, while others
+expose only ordered start and completion signals, an encrypted result, or a
+summary through an optional hook.
+
+## What we propose to do about it
+
+> What are you proposing to improve the situation?
+
+Add `compaction_update` and `compaction_summary_chunk` to `SessionUpdate` in
+ACP v1 and v2. The first `compaction_update` for an ID creates a compaction
+entity at that position in the session timeline. Later updates and summary
+chunks with the same ID update that entity in place.
+
+A live compaction starts with:
+
+```json
+{
+ "sessionUpdate": "compaction_update",
+ "compactionId": "cmp_001",
+ "status": "in_progress"
+}
+```
+
+If the summary is available incrementally, the Agent can append content while
+the compaction is in progress:
+
+```json
+{
+ "sessionUpdate": "compaction_summary_chunk",
+ "compactionId": "cmp_001",
+ "content": {
+ "type": "text",
+ "text": "## Retained context\n\n"
+ }
+}
+```
+
+The Agent finishes the same entity by reusing its ID. A non-streaming Agent can
+include the complete summary, while a streaming Agent can use this field as an
+authoritative final replacement:
+
+```json
+{
+ "sessionUpdate": "compaction_update",
+ "compactionId": "cmp_001",
+ "status": "completed",
+ "summary": [
+ {
+ "type": "text",
+ "text": "## Retained context\n\nThe user is updating the ACP schema..."
+ }
+ ]
+}
+```
+
+### Identity and lifecycle
+
+`compactionId` is an opaque, Agent-owned string. It is required,
+non-null, unique within the session, and never reused for another compaction.
+
+`status` is required and non-null on every update. Its initial values are:
+
+- `in_progress` - Compaction has started and has not finished.
+- `completed` - Compaction finished successfully.
+- `failed` - Compaction finished unsuccessfully.
+- `cancelled` - Compaction was cancelled before it finished.
+
+`CompactionStatus` is open in both protocol versions from its
+introduction and follows the
+[v2 enum-extension rules](/rfds/v2/enum-variant-extension). Values beginning
+with `_` are reserved for implementation-specific extensions, while other
+unknown values are reserved for future ACP statuses. Clients preserve an
+unknown string and present an opaque generic state without inferring lifecycle
+or control behavior from it.
+
+The normal transition is `in_progress` to one terminal status. An Agent may
+send a terminal status as the first update when replaying history or when its
+underlying runtime only exposes completed compactions. After emitting
+`in_progress`, the Agent must eventually put the entity into exactly one
+terminal status when that compaction ends, unless the session or connection
+ends before the update can be delivered.
+
+The first `compaction_update` fixes the entity's timeline position relative to
+other ID-addressed entities: it follows entities first seen earlier and
+precedes entities first seen later. An Agent must send that update before any
+`compaction_summary_chunk` for the ID. Later patches or chunks for any of those
+entities do not move them or split one entity around the compaction. A Client
+may render an in-progress indicator and replace it with a completed, failed, or
+cancelled presentation when the terminal update arrives.
+
+### Optional fields and patch semantics
+
+The update has three optional, nullable patch fields:
+
+- `summary` is an array of `ContentBlock` values containing the
+ unencrypted, user-displayable content produced or retained by a successful
+ compaction. It should faithfully represent the retained summary while
+ excluding internal prompt framing or instructions. Text blocks may contain
+ Markdown. It is not generic content such as `Compaction completed`.
+- `error` is a human-readable string describing why compaction failed.
+- `_meta` is reserved for extensibility and follows ACP's existing `_meta`
+ rules.
+
+For each patch field, omission leaves the stored value unchanged, `null`
+clears it, and a concrete value replaces it. On a first-seen ID, omission and
+`null` both start with no value. For `summary`, both `null` and `[]` clear the
+current content. A non-empty `summary` is only valid with `completed`, and
+`error` is only valid with `failed`.
+
+### Streaming summary content
+
+`compaction_summary_chunk` contains a required, non-null `compactionId` and one
+required, non-null `ContentBlock` in `content`. Its optional nullable `_meta`,
+when present, is scoped to that chunk; omission and `null` both mean that the
+Agent supplied no chunk metadata.
+
+Clients apply `compaction_update` and `compaction_summary_chunk` notifications
+in receive order for each `compactionId`. A chunk appends its `content` block to
+the current summary. A later `compaction_update` with a concrete `summary`
+array replaces all content accumulated from earlier updates and chunks;
+subsequent chunks append to that replacement. `summary: []` or `summary: null`
+clears the accumulated content.
+
+Agents may send summary chunks only after an `in_progress` update and before a
+terminal update. A `completed` update may omit `summary` to retain the content
+accumulated from chunks, or include the complete summary as an authoritative
+final replacement.
+
+Agents should omit `summary` when no unencrypted, user-displayable summary is
+available or when exposing it could reveal context that was not otherwise
+user-visible.
+
+### Version-specific capability
+
+For v1, add an optional `compaction` object to `ClientSessionCapabilities`:
+
+```json
+{
+ "clientCapabilities": {
+ "session": {
+ "compaction": {}
+ }
+ }
+}
+```
+
+The object appears at `clientCapabilities.session.compaction` in the v1
+`initialize` request. Omitting `session`, setting `session` to `null`, omitting
+`compaction`, or setting `compaction` to `null` all mean the Client does not
+advertise support. Supplying `{}` for `compaction` means the Client implements
+the ID, update, chunk, placement, and replay semantics in this RFD. Agents must
+only send `compaction_update` or `compaction_summary_chunk` to a v1 Client that
+advertises this capability.
+
+V2 does not add or require a capability.
+
+## Shiny future
+
+> How will things will play out once this feature exists?
+
+Users can see context compaction begin and finish at the point where it
+occurred. Clients can keep one stable timeline row, optionally make the retained
+summary expandable, and accurately reconstruct historical compaction boundaries
+after reconnecting.
+
+Agents no longer need to turn an internal lifecycle event into conversational
+text. Implementations with rich provider data can expose the summary, while
+implementations with only lifecycle signals remain fully conformant.
+
+## Implementation details and plan
+
+> Tell me more about your implementation. What is your detailed implementation plan?
+
+1. Add `compaction` to v1 `ClientSessionCapabilities` behind an unstable
+ feature; do not add a v2 capability.
+2. Add `CompactionId`, `CompactionStatus`, `CompactionUpdate`, and
+ `CompactionSummaryChunk` to both protocol versions.
+3. Add `compaction_update` and `compaction_summary_chunk` to both
+ `SessionUpdate` unions.
+4. Implement the same open status enum in both versions and preserve known and
+ unknown statuses through v1/v2 conversion.
+5. Document lifecycle, patch, placement, replay, and summary-safety semantics
+ in both protocol versions.
+6. Add serialization, v1 capability-gating, v2 unknown-update, transition,
+ update/chunk ordering, replay materialization, and conversion tests, then
+ update example Clients and Agents.
+
+## Frequently asked questions
+
+> What questions have arisen over the course of authoring this document or during subsequent discussions?
+
+### Why is the capability required in v1?
+
+Agents currently fall back to agent text because compaction can take a while
+and it is useful to tell the user what is happening. The capability lets an
+Agent send `compaction_update` when the Client supports it while preserving
+that fallback for older v1 Clients.
+
+### Does `summary` contain the Agent's complete replacement history?
+
+No. Some runtimes retain compaction output as multiple role-bearing model
+history items, potentially including developer instructions, retained user
+messages, or encrypted provider data. `summary` contains only the
+user-displayable projection of that result as content blocks, without internal
+framing or hidden instructions. It is optional because some runtimes expose no
+safe user-displayable projection.
+
+### Why is `summary` a `ContentBlock[]`?
+
+ACP Clients already process `ContentBlock` values in Agent output. Reusing that
+shape preserves multiple or non-text blocks when a runtime exposes them without
+creating another content representation. A text-only runtime sends one text
+block, and a runtime with no user-displayable summary omits the field.
+
+The array is still a summary artifact, not a sequence of ACP messages and not a
+lossless encoding of the Agent's internal replacement history.
+
+### Why can `summary` be streamed?
+
+Some runtimes produce summary text incrementally, and ACP v2 already composes
+append-only content chunks with authoritative replacement snapshots for
+messages and tool calls. Compaction follows the same pattern. Runtimes that
+only expose a completed result send one `compaction_update`, and replay always
+uses that materialized form.
+
+### Should the Client collapse earlier messages after compaction?
+
+That is a local presentation choice and is not implied by this update. The
+Client may visually mark or group the earlier portion of the transcript, but it
+must retain whatever history the surrounding session and replay contracts
+require.
+
+### How does this interact with `usage_update`?
+
+They report different facts. `compaction_update` records a lifecycle
+boundary and optional retained summary. `usage_update` reports current context
+window utilization and cost. An Agent will commonly send a lower usage value
+after compaction, but neither update substitutes for the other.
+
+### What alternative approaches did you consider, and why did you settle on this one?
+
+**Agent messages** - They are widely renderable, but they turn protocol
+activity into conversation content and cannot replace one stable entity in
+place.
+
+**Separate start and finish events** - Simple to emit, but force Clients to
+correlate events heuristically and replay transient progress instead of one
+materialized entity.
+
+## Revision history
+
+- 2026-07-22: Initial draft.
diff --git a/docs/rfds/updates.mdx b/docs/rfds/updates.mdx
index 1b66a1af..93728387 100644
--- a/docs/rfds/updates.mdx
+++ b/docs/rfds/updates.mdx
@@ -6,6 +6,13 @@ rss: true
This page tracks lifecycle changes for ACP Requests for Dialog. For broader ACP announcements, see [Updates](/updates).
+
+## Session Compaction RFD moves to Draft stage
+
+The RFD for reporting ID-addressed context compaction lifecycle and optional retained summaries in ACP v1 and v2 has moved to Draft stage. Please review the [RFD](/rfds/session-compaction) for more information and provide feedback while the entity and replay semantics are refined.
+
+
+
## auth/status RFD moves to Draft stage