Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
97 commits
Select commit Hold shift + click to select a range
2750598
πŸ€– feat: define token-budget context window contracts
ThomasK33 Sep 5, 2026
3058044
πŸ€– feat: wire context-budget rollover lifecycle
ThomasK33 Sep 5, 2026
0d751d7
πŸ€– feat: present token-budget context windows and document rollover po…
ThomasK33 Sep 5, 2026
49cd04a
πŸ€– feat: complete token-budget presentation metadata contracts
ThomasK33 Sep 5, 2026
4dda23e
πŸ€– fix: refresh context notes after memory tools and clean budget refu…
ThomasK33 Sep 5, 2026
f2419f0
πŸ€– feat: add bounded session history recovery across context windows
ThomasK33 Sep 5, 2026
4503008
πŸ€– fix: guard budget continuations against interrupt supersession
ThomasK33 Sep 5, 2026
e666e28
πŸ€– docs: describe atomic token-budget history batches accurately
ThomasK33 Sep 5, 2026
baee222
πŸ€– feat: reserve context notes and preflight assembled token budgets
ThomasK33 Sep 5, 2026
f81098c
πŸ€– fix: preserve structured budget errors and suppress unchanged retries
ThomasK33 Sep 5, 2026
3c1adb2
πŸ€– fix: pass effective memory permissions to budget settlement
ThomasK33 Sep 5, 2026
eae3d1d
πŸ€– fix: preserve flush opportunity and sync token-budget documentation
ThomasK33 Sep 5, 2026
a71068c
πŸ€– tests: cover token-budget lifecycle and settled step stopping
ThomasK33 Sep 5, 2026
8c0f945
πŸ€– tests: align rollover fixtures with settled budget contracts
ThomasK33 Sep 5, 2026
39c74e0
πŸ€– fix: open collapsed sidebar in token-budget settings story
ThomasK33 Sep 5, 2026
e4489c7
πŸ€– fix: preserve explicit compaction recovery with token budgets
ThomasK33 Sep 5, 2026
90ae593
πŸ€– fix: align session history inputs and paging with D9
ThomasK33 Sep 5, 2026
c90c03e
πŸ€– fix: finalize rollover recovery and token-budget presentation
ThomasK33 Sep 5, 2026
c0d737e
πŸ€– fix: enforce malformed reset privacy and rotate published history b…
ThomasK33 Sep 5, 2026
3ce1127
πŸ€– fix: preserve policy and request context across token-budget rollovers
ThomasK33 Sep 5, 2026
b176141
πŸ€– fix: scale token-budget reserves for small context windows
ThomasK33 Sep 5, 2026
546bf05
πŸ€– fix: display the effective token-budget rollover threshold
ThomasK33 Sep 5, 2026
32fb9a3
πŸ€– fix: retain accepted rollover inputs and isolate rejected context
ThomasK33 Sep 5, 2026
2b18a51
πŸ€– fix: bound history identifiers without stalling recovery cursors
ThomasK33 Sep 5, 2026
d8bdae6
πŸ€– fix: recover from terminal budget rejection and damaged preludes
ThomasK33 Sep 5, 2026
05c3f4d
πŸ€– fix: require complete rollover validation for history privacy excep…
ThomasK33 Sep 5, 2026
ba06f05
πŸ€– fix: atomically reject budget request payloads
ThomasK33 Sep 5, 2026
af7406c
πŸ€– fix: preserve reset floors and reject asynchronous budget failures
ThomasK33 Sep 5, 2026
d9d600e
πŸ€– fix: sanitize persisted token-budget counters
ThomasK33 Sep 5, 2026
9d2051d
πŸ€– merge: preserve routing-aware token budgets on current main
ThomasK33 Sep 5, 2026
df8ee64
πŸ€– fix: detect escaped reset markers in bounded history scans
ThomasK33 Sep 5, 2026
f3681fb
πŸ€– fix: preserve reset privacy across malformed history fragments
ThomasK33 Sep 5, 2026
e06b1a0
πŸ€– fix: keep legacy window IDs out of rollover instructions
ThomasK33 Sep 5, 2026
ec29277
πŸ€– fix: require history access only for eligible context rollovers
ThomasK33 Sep 5, 2026
23bd88c
πŸ€– fix: preserve reset privacy through corrupt separators and history …
ThomasK33 Sep 5, 2026
52971d3
πŸ€– fix: recognize reset tokens across arbitrary malformed separators
ThomasK33 Sep 5, 2026
b7f2081
πŸ€– fix: normalize persisted request prelude references
ThomasK33 Sep 5, 2026
be6e1f0
πŸ€– fix: terminate rejected retries and preserve append-only budget sends
ThomasK33 Sep 5, 2026
5d0e8ea
πŸ€– fix: certify history cursor appends with durable cross-process rece…
ThomasK33 Sep 5, 2026
00a1560
πŸ€– tests: cover terminal rejected-tail replay and document cursor prov…
ThomasK33 Sep 5, 2026
e153c3c
πŸ€– merge: reconcile current main with token-budget context windows
ThomasK33 Sep 5, 2026
a231fd6
πŸ€– fix: reject special-file history receipts without blocking
ThomasK33 Sep 5, 2026
96b9245
πŸ€– fix: preserve raw history reset floors and sanitize request preludes
ThomasK33 Sep 5, 2026
1cbd1f2
πŸ€– fix: retain unreadable reset floors through partial history truncation
ThomasK33 Sep 5, 2026
12ea025
πŸ€– fix: separate unterminated archive rows during truncation
ThomasK33 Sep 5, 2026
730d649
πŸ€– fix: recover budget usage and own copied retry skill snapshots
ThomasK33 Sep 5, 2026
416b79e
πŸ€– fix: harden history rewrites and truncation marker compatibility
ThomasK33 Sep 5, 2026
2828ad5
πŸ€– fix: validate persisted message parts before history operations
ThomasK33 Sep 5, 2026
fb2b82a
πŸ€– fix: quarantine rejected context payloads in downgrade-safe capsules
ThomasK33 Sep 6, 2026
a5eb5ef
πŸ€– tests: verify copied rejection capsules and document downgrade safety
ThomasK33 Sep 6, 2026
c77d0d8
πŸ€– fix: reject ambiguous reset keys and select the newest request iden…
ThomasK33 Sep 6, 2026
d3c5840
πŸ€– fix: honor inherited tool policy for session history
ThomasK33 Sep 6, 2026
1472e6b
πŸ€– fix: slice durable context boundaries before filtering hidden rows
ThomasK33 Sep 6, 2026
1224e85
πŸ€– fix: recognize hex-escaped history reset privacy floors
ThomasK33 Sep 6, 2026
255a7fd
πŸ€– fix: clamp provider history to unreadable reset floors
ThomasK33 Sep 6, 2026
e99a2f2
πŸ€– tests: preserve replay-boundary coverage after provider clamping
ThomasK33 Sep 6, 2026
a575706
πŸ€– fix: stop treating historical input usage as system overhead
ThomasK33 Sep 6, 2026
939a1bf
πŸ€– fix: retain active history without verified replay proof
ThomasK33 Sep 6, 2026
a01ca86
πŸ€– docs: explain conservative replay retention
ThomasK33 Sep 6, 2026
b4fcc8f
πŸ€– fix: tolerate corrupted persisted step boundaries
ThomasK33 Sep 6, 2026
d24f321
πŸ€– fix: pin workspace request middleware before context rollover
ThomasK33 Sep 6, 2026
b386a77
πŸ€– fix: apply goal safety when manual token-budget input is rejected
ThomasK33 Sep 6, 2026
be64254
πŸ€– fix: identify exact history rows and preserve Unicode search offsets
ThomasK33 Sep 6, 2026
21be114
πŸ€– fix: bind exact history row references to append epochs
ThomasK33 Sep 6, 2026
5e17c08
πŸ€– fix: recover readable rows through exact history references
ThomasK33 Sep 6, 2026
4d112b8
πŸ€– fix: enforce token-budget hard ceilings across dense input and sett…
ThomasK33 Sep 6, 2026
e968cb8
πŸ€– docs: describe real-encoding guards and settled hard stops
ThomasK33 Sep 6, 2026
67fa40a
πŸ€– fix: repair rotation retry tails and distinguish reset data from bo…
ThomasK33 Sep 6, 2026
15baf40
πŸ€– fix: reconcile main delivered-completion lifecycle
ThomasK33 Sep 6, 2026
36e6181
πŸ€– fix: preserve surrogate pairs in history character pages
ThomasK33 Sep 6, 2026
57db4f0
πŸ€– fix: preserve ordered control evidence outside provider filtering
ThomasK33 Sep 6, 2026
14078eb
πŸ€– fix: retain control input with untrustworthy outer metadata
ThomasK33 Sep 6, 2026
f60fea6
πŸ€– fix: normalize legacy control metadata independently of payload val…
ThomasK33 Sep 6, 2026
8f384c0
πŸ€– tests: retain the hard-ceiling contract when automatic rollover is off
ThomasK33 Sep 6, 2026
5ad9067
πŸ€– fix: reject conflicting rollover rows and delimit torn ordinary app…
ThomasK33 Sep 6, 2026
824267f
πŸ€– fix: admit materialized preludes before context rollover
ThomasK33 Sep 6, 2026
24fca74
πŸ€– fix: admit emergency retry preludes against failing model
ThomasK33 Sep 6, 2026
537a0ad
πŸ€– refactor: reconcile token budgets with centralized turn ownership
ThomasK33 Sep 6, 2026
57b5a4e
πŸ€– fix: add token-budget notes after the ordinary hot-memory set
ThomasK33 Sep 7, 2026
c9f1adc
πŸ€– refactor: reconcile token budgets with scoped turn lifetimes
ThomasK33 Sep 7, 2026
797c94e
πŸ€– fix: retain send lifetime through budget rejection writes
ThomasK33 Sep 7, 2026
620bee3
πŸ€– fix: retain manual reset window kinds across history pages
ThomasK33 Sep 7, 2026
3199e30
πŸ€– fix: budget provider-visible text and active tool schemas
ThomasK33 Sep 7, 2026
9117c85
πŸ€– docs: describe provider-visible budget admission
ThomasK33 Sep 7, 2026
b0d2c45
πŸ€– refactor: merge awaitable turn lifetimes into token-budget branch
ThomasK33 Sep 7, 2026
5ad12d0
πŸ€– fix: admit the complete pinned request before context rollover
ThomasK33 Sep 7, 2026
9cbe660
πŸ€– tests: cover prepared rollover ownership and reset survival
ThomasK33 Sep 7, 2026
bd8b5ee
πŸ€– fix: detach admission cancellation from accepted prepared wakes
ThomasK33 Sep 7, 2026
8e83c0f
πŸ€– fix: preserve prepared wake delivery after failed rollback
ThomasK33 Sep 7, 2026
3b0bf89
πŸ€– docs: describe pinned request admission before rollover
ThomasK33 Sep 7, 2026
957f9fb
πŸ€– fix: preserve ordinary history JSON and report missing item failures
ThomasK33 Sep 7, 2026
d98d937
πŸ€– fix: count JSON structure and preserve copied file baselines
ThomasK33 Sep 7, 2026
f0f2562
πŸ€– docs: clarify JSON budget bounds and copied file tracking
ThomasK33 Sep 7, 2026
74ed28b
πŸ€– fix: merge main reconnect ownership into token-budget branch
ThomasK33 Sep 7, 2026
2e73439
πŸ€– tests: make unknown history rewrite stamp changes deterministic
ThomasK33 Sep 7, 2026
fe1f14d
πŸ€– fix: prevent boundary skips from crossing manual history resets
ThomasK33 Sep 7, 2026
3e093e6
πŸ€– docs: clarify fixed-stamp append provenance limits
ThomasK33 Sep 7, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 64 additions & 0 deletions docs/adr/0005-token-budget-context-windows.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
---
title: Token-Budget Context Windows
description: An opt-in automatic reset policy with bounded retrieval and a manual-reset privacy floor
---

# 0005. Automatic Rollover Can Retrieve Earlier Context Windows

## Status

Accepted. Amends only consequence 2 of [ADR 0003](./0003-context-boundaries-for-compaction-and-reset.md) for automatic token-budget rollover.

## Context

Repeated automatic summaries lose detail and consume inference tokens. An opt-in policy can instead start a fresh Active Conversation Context while retaining Transcript History for explicit, bounded retrieval. Manual resets must keep their privacy semantics.

## Decision

Automatic rollover uses a provider-invisible Context Reset Boundary followed by a provider-visible synthetic lead-in. The lead-in identifies the new window and offers `session_history` retrieval; it does not summarize old messages. Earlier windows are retrievable only while the experiment is enabled and never across the newest manual reset. Manual `/clear --soft` remains provider-invisible, adds no lead-in, and establishes that privacy floor.

Manual `/compact`, idle compaction, continuous compaction, and effective RLM retain their existing behavior and take precedence over rollover. Existing edited-file carryover is unchanged. With automatic handling disabled, no rollover or flush warning is emitted, but hard assembled-request preflight still blocks oversized requests. `session_history` follows ordinary inherited agent and caller tool policy: an explicit tool name or matching wildcard must grant access, and later matching rules can remove it. The experiment does not widen narrow allowlists; built-in Exec and Plan grant access through `.*`, and Explore inherits that grant. If effective policy omits or disables history access, a rollover that would seal existing context is blocked rather than falling back to lossy summaries. A fitting first request in an empty or internal-only window does not require history access.

Before a rollover can clear context state or append a boundary, request admission reconciles the workspace's lazy plugin hooks and captures an immutable, ordered snapshot of the applicable request-assembly registrations. Unrestricted middleware is uncertified even when it appears benign: it could remove a tool or mutate its implementation/schema in place. Such middleware blocks rollover; it is never overridden by restoring a denied tool. Explicit workspace scopes are enforced during dispatch, so registrations for other workspaces do not block admission. Only the context-only registration adapter certifies toolset preservation: it receives no tool references and writes back system text alone. The sandboxed plugin context adapter uses this path.

The rollover turn's primary and fallback requests run the admitted snapshot; thinking rebuilds retain that assembled context and toolset. Neither consults later registry changes or constructs the toolset before cleanup. In-process automatic retries retain the same snapshot; it is never serialized into history or send options. Registration/unregistration changes affect subsequent admissions. Plugin disposal and managed-plugin mutation epochs remain live revocation checks, and hook execution reacquires sandbox mounts rather than retaining a disposed kernel. Ordinary non-rollover requests retain live middleware filtering.

A once-per-window warning offers a settled tool step to write the conventional `workspace/context-notes.md` file (up to 8 KiB, if writable). While token-budget mode is active, existing notes can be appended after the unchanged ordinary hot-memory selection, allowing up to nine entries without displacing the normal eight. This additional excerpt has its own 8 KiB / 2,000-token allowance, including formatting, rather than consuming the ordinary selection's budgets. Notes already selected normally are not duplicated. Memory and Memory Hot Set remain required; when token-budget mode is inactive, the file follows ordinary memory-selection rules. Rollover waits for a settled tool step, preserves tool call/result pairs, and allows only one pending rollover to be handled on the next send. Restart stays paused: it does not resurrect a queued continuation; the next message derives context pressure from persisted history.

The reset, lead-in, and triggering message or continuation are committed as one all-or-nothing batch before continuation. `HistoryService.appendManyToHistory` uses `writeFileAtomic` (temporary file and rename) under the cross-process history lock, rather than `fs.appendFile`; the current writer does not expose a torn batch prefix on crash. Recovery tests must still cover partial prefixes from legacy or externally modified histories without duplicating rollover or resurrecting queued work. A payload estimated not to fit even in a fresh window is rejected before a provider request.

Fresh-request, assembled-request, and settled-tool-output hard guards use the resolved model/capability encoding, bypassing approximation mode only for those counts. Large strings are counted in codepoint-safe chunks with boundary slack to bound long-run encoding work; encoding failures do not silently fall back to character ratios. Provider-family encodings and media/framing allowances remain estimates, so provider context-overflow handling remains a backstop. At a settled hard ceiling with automatic handling disabled, the turn stops without warning, rollover, continuation, or preflight quarantine; completed sibling tool results remain durable.

Ordinary text and JSON remain text even when they contain data URLs or media-shaped objects. Omitted JSON punctuation and escape expansion receive a conservative byte-based token allowance instead of relying only on the character heuristic. Only genuine provider media parts and supported tool-output media wrappers use media allowances. With Tool Search, preflight counts only advertised schemas while retaining the full tool map for execution. Each provider step is checked again after thinking/media transforms against the attempt's pinned model limit, including newly activated schemas. A per-step budget failure blocks without an emergency rollover; completed tool results remain durable. Builder preflight retains its existing recoverable rollover path.

Before a proposed rollover clears context state or appends its boundary, the existing builder prepares the complete candidate request: pinned system/middleware text, fresh memory context, actual advertised schemas, and the exact candidate rows. Admission failure releases prepared resources without sealing the current window or clearing its context-scoped state. Successful admission persists those rows and starts the same one-shot prepared request, avoiding a second tool/system/hook assembly and pre-acceptance assistant-placeholder or stream registration. Candidate memory context is promoted only after the rollover append succeeds. The admission abort link is limited to preparation. Once the candidate is ready, explicit cancellation/rollback guards decide whether to discard it or retain delivery; normal turn interruption and disposal remain effective.

An in-process emergency retry restores only the copied file snapshot's original accepted tracking baseline, after the rollover batch commits and its owner is still current. It does not reread snapshot content, adopt a newer tracker baseline, or restore unrelated old-window files. Normal in-memory tracker lifetime is unchanged.

Only context-scoped cache, persisted carryover, and sandbox clearing runs before append. This ordering is deliberately fail-closed: a crash after publication must not reopen a fresh window with stale pre-reset carryover or kernel state. If cleanup succeeds but cancellation or append failure prevents publication, the old transcript remains with that disposable state cleared; it is not restored because a failed acknowledgment may still mean publication succeeded. Cancellation and admission are checked before cleanup and again before append. Branch-summary clearing and epoch notification run after append; cleanup failure must prevent a provider request. When rollover invalidates other sends, its own caller must adopt the updated epoch before continuing.

### Rejected request retention across downgrades

Rejected inputs and their owned snapshots are transcript-only. They are stored as empty, non-partial assistant records, retaining their identity and sequence; the original role, content, and display metadata live inside a new opaque metadata field. No original skill, file, command, or peer control metadata remains active on the outer record. Current display/export code can recover the original transcript projection without restoring it to provider history.

The preceding request assembler already excludes empty assistant records, so downgrading cannot replay rejected payloads merely because it ignores the new rejection flag. Older builds may not display the quarantined original content, but preserve it for a subsequent upgrade. Partial-truncation transaction markers likewise retain legacy decoded-text digests in their existing fields and add separately versioned byte digests, allowing both versions to recognize an accepted rewrite containing invalid UTF-8.

### Append-stable retrieval cursors

Head/tail hashes alone cannot distinguish an append from an interior rewrite followed by an append. Retrieval therefore uses a constant-size durable append receipt in addition to the bounded scan cursor. This receipt is cursor-safety metadata, not a rollover journal or a second copy of the transcript.

All cooperative history writers share the existing cross-process history lock. Before changing transcript files, a writer publishes a pending receipt; failure to invalidate the old receipt aborts the mutation. Only positively verified append operations may retain the receipt's epoch; a rewrite, truncation, rotation, recovery, or unexplained file change invalidates it. A stable receipt binds the epoch to the resulting chat and archive file stamps. Failure to finalize the receipt after accepting a history write expires cursors rather than reporting the accepted write as failed. Readers hold the same lock and validate the receipt and stamps before and after each bounded page, without running recovery during the scan. The bounded append scan still checks for newly added manual-reset privacy floors.

Append stability is guaranteed for tracked `HistoryService` appends, including tool-result appends and appends made by another backend process. Direct filesystem edits or appends observed outside a tracked transaction are untracked: existing cursors fail closed instead of treating file growth as proof of append-only history. Missing, malformed, pending, or mismatched receipts also expire existing cursors. A new query can establish a fresh baseline under the same history lock; it cannot revive an old cursor. Backend restarts continue to expire authenticated cursors.

The receipt assumes cooperative transcript writers honor the history lock and tracked mutation protocol. It detects untracked edits that change the observed file identity, size, or timestamps; fixed stamps do not prove content identity. A same-size rewrite can leave all observed stamps unchanged within a filesystem timestamp tick, even without an adversarial writer. Such changes, including edits racing an append/stat interval, are indistinguishable from no write under the bounded receipt contract. Stronger detection requires filesystem/write isolation or verification of the entire prior prefix, not bounded file stamps.

The receipt does not turn history readers into unbounded prefix verifiers. Transcript scan and result budgets remain unchanged, and the receipt itself has a fixed-size read limit. Raw malformed reset candidates must also survive automatic history rewrites: invalidating an old cursor cannot repair a privacy floor that a writer erased before a new query.

Archived sequence coverage is not proof that an active row is a replay. Retrieval retains rows with reused sequences so repaired or imported content remains accessible; possible physical replay duplicates may therefore appear in results.

## Consequences

- `session_history` list/search/read is bounded: 16 KiB per tool result, 2 MiB scanned, 500 rows, and a 1 MiB per-line cap. Retrieval is scoped to the calling workspace and the manual-reset privacy floor.
- Old windows remain on disk and in transcript display/export. The lead-in stays hidden in normal transcript display; warnings render as machine messages, not human prompts.
- Opting out disables retrieval, not retention. ADR 0003's remaining decisions and consequences are unchanged.
1 change: 1 addition & 0 deletions docs/docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
"workspaces/compaction",
"workspaces/compaction/manual",
"workspaces/compaction/automatic",
"workspaces/compaction/token-budget",
"workspaces/compaction/customization"
]
},
Expand Down
16 changes: 16 additions & 0 deletions docs/hooks/tools.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -644,6 +644,22 @@ If a value is too large for the environment, it may be omitted (not set). Xum al

</details>

<details>
<summary>session_history (8)</summary>

| Env var | JSON path | Type | Description |
| ----------------------------- | -------------- | ------ | ----------- |
| `XUM_TOOL_INPUT_ACTION` | `action` | enum | β€” |
| `XUM_TOOL_INPUT_CURSOR` | `cursor` | string | β€” |
| `XUM_TOOL_INPUT_ITEM_ID` | `item_id` | string | β€” |
| `XUM_TOOL_INPUT_LIMIT` | `limit` | number | β€” |
| `XUM_TOOL_INPUT_LIMIT_CHARS` | `limit_chars` | number | β€” |
| `XUM_TOOL_INPUT_OFFSET_CHARS` | `offset_chars` | number | β€” |
| `XUM_TOOL_INPUT_QUERY` | `query` | string | β€” |
| `XUM_TOOL_INPUT_WINDOW_ID` | `window_id` | string | β€” |

</details>

<details>
<summary>set_goal (5)</summary>

Expand Down
2 changes: 2 additions & 0 deletions docs/workspaces/compaction/automatic.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ Xum can run `/compact` for you to keep context size manageable. There are two ty
- **Usage-based**: Compacts when your conversation reaches a configurable percentage of the model's context window
- **Idle-based**: Optionally compacts inactive workspaces after a period of time

The opt-in [token-budget context windows experiment](/workspaces/compaction/token-budget) replaces usage-triggered summaries with fresh windows and on-demand history retrieval. Manual and idle compaction are unchanged.

## Usage-based auto-compaction

When enabled, Xum monitors your context usage and:
Expand Down
31 changes: 31 additions & 0 deletions docs/workspaces/compaction/token-budget.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
---
title: Token-Budget Context Windows
description: Start fresh context windows without automatic summaries and retrieve earlier work on demand
---

Enable **Token-budget context windows** in **Settings β†’ Experiments** to replace usage-triggered automatic summaries with fresh context windows. The experiment is off by default.

## Threshold and precedence

Use the existing context-usage slider to choose the per-model threshold. The **Rolls over by N%** label includes the five-percentage-point force buffer: a 70% slider setting displays **Rolls over by 75%**. Automatic rollover is evaluated when sending and after a settled tool step. The displayed percentage is an upper bound; the hard request ceiling takes precedence if reached first. Rollover starts a fresh window without summarizing earlier messages. The transcript shows a **Context window rollover** divider; earlier messages remain on disk, in the UI, and in exports.

- Manual `/compact` and idle compaction still summarize normally.
- Continuous compaction and effective RLM take precedence over rollover.
- Setting the usage threshold to **100%** disables automatic rollover and its warning. Hard request-size checks still apply, including after settled tool steps: the turn can pause without queuing a rollover or discarding completed tool results.
- `session_history` must be allowed by the agent's inherited tool policy and any caller restrictions. Built-in Exec, Plan, and Explore already allow it. Narrow custom agents can add `session_history` or a matching wildcard to `tools.add`. If access is omitted or disabled, rollover pauses before sealing existing context instead of falling back to a lossy summary.

Rollover also pauses when applicable request middleware can change the toolset, before clearing context state or saving a boundary. Context-only integrations, including sandboxed plugin context hooks, remain supported. Xum pins the workspace's applicable hook registrations when admitting a rollover and uses that snapshot throughout the turn and its fallback attempts; later registration changes apply to subsequent requests. Plugin revocation still takes effect. Hooks explicitly scoped to another workspace do not block rollover. Ordinary requests and manual `/compact` retain their existing middleware behavior.

## Keeping useful context

Once per window, a machine-authored warning asks the agent to write important context to the conventional `workspace/context-notes.md` file, up to **8 KiB**, if the workspace is writable. This is an opportunity to preserve notes, not a guarantee that the agent writes them. While token-budget mode is active, Xum can preload the notes as an **additional ninth memory**, without replacing the normal eight or using their existing byte/token budgets. The extra excerpt is separately bounded to **8 KiB / 2,000 tokens**, including formatting, and is not duplicated if already selected normally. This still requires **Memory** and **Memory Hot Set**; the experiment does not enable either. With token-budget mode inactive, notes follow the ordinary memory-selection rules.

The next window receives a model-only lead-in, not a summary. While the experiment is enabled, the agent can use `session_history` to list windows, search, or read earlier messages in the same workspace. Results are capped at **16 KiB** per call, with scans bounded to **2 MiB**, **500 rows**, and **1 MiB per line**. Large histories may require further bounded calls.

The newest manual `/clear --soft` is a privacy floor: the tool cannot retrieve messages before it. Manual reset behavior and edited-file carryover are unchanged. Turning the experiment off removes retrieval access without deleting old windows.

## Pauses and size limits

Rollover stops only after a tool step settles, preserving tool call/result pairs. Only one rollover may be pending; it is handled on the next send. Restart leaves the workspace paused rather than resurrecting a queued continuation, and the next message re-evaluates pressure from history.

The boundary, lead-in, and triggering message or continuation are saved as one atomic, all-or-nothing batch. Recovery also tolerates incomplete batches in legacy or externally modified histories. Requests estimated to exceed a fresh window are blocked before contacting the provider; rollover cannot make oversized attachments or instructions fit. Text guards use real encodings, but provider-family, media, and framing estimates can still differ from the provider's accounting. Pasted data URLs and ordinary tool JSON count as text, not as image attachments. With Tool Search, deferred schemas count only when advertised; each provider step rechecks activated tools and transformed messages. A failed step preflight pauses without starting another rollover. Before a rollover clears the current context, the complete pinned future requestβ€”including system instructions, memory, and advertised toolsβ€”must also fit. If admission fails, the current window stays open. An admitted request is prepared once and reused after the boundary is saved.
Loading
Loading