# How Retention Policies Are Configured in Mako's Context Management

> Discover how Mako configures retention policies using terminal scroll-back limits and runtime-policy size constraints. Learn to manage data effectively.

- Repository: [The Apache Software Foundation/maka](https://github.com/apache/maka)
- Tags: how-to-guide
- Published: 2026-09-06

---

**Mako configures retention policies through two complementary mechanisms: terminal scroll-back limits enforced by `trackScrollbackRetention` in [`pty-screen-collector.ts`](https://github.com/apache/maka/blob/main/pty-screen-collector.ts), and runtime-policy size constraints governed by `POLICY_DOCUMENT_MAX_BYTES` in [`policy-document.ts`](https://github.com/apache/maka/blob/main/policy-document.ts).**

Mako's context management system controls how much data persists across user sessions, balancing memory efficiency with session continuity. The **Apache Mako** project implements these controls through hard limits on terminal output history and JSON policy document sizes, with configuration exposed via TypeScript constants and store APIs.

## Terminal Scroll‑Back Retention

The PTY screen collector enforces a strict ceiling on how many rows of terminal history remain available after scrolling off-screen.

### The `trackScrollbackRetention` Method

Located in [`packages/runtime/src/pty-screen-collector.ts`](https://github.com/apache/maka/blob/main/packages/runtime/src/pty-screen-collector.ts), this private method evaluates every scroll event against the `PTY_SCROLLBACK_ROWS` threshold:

```typescript
// packages/runtime/src/pty-screen-collector.ts
private trackScrollbackRetention(): void {
  if (this.terminal.buffer.active.type !== 'normal') return;
  if (this.suppressNextNormalScrollRetention) {
    this.suppressNextNormalScrollRetention = false;
    this.normalBufferAtScrollbackLimit = this.terminal.buffer.normal.baseY >= PTY_SCROLLBACK_ROWS;
    return;
  }
  const atLimit = this.terminal.buffer.normal.baseY >= PTY_SCROLLBACK_ROWS;
  if (atLimit && this.normalBufferAtScrollbackLimit) this.historyTruncated = true;
  this.normalBufferAtScrollbackLimit = atLimit;
}

```

**Key behaviors:**

- **`baseY`** — tracks how many rows have scrolled off the visible terminal
- **`PTY_SCROLLBACK_ROWS`** — the hard retention limit (default: 10,000 rows)
- **`historyTruncated`** — flag set when the limit is reached twice consecutively, indicating data loss

The `suppressNextNormalScrollRetention` flag prevents false truncation signals during terminal resets or control sequence processing.

### Adjusting the Scroll‑Back Limit

Modify the exported constant to change retention policy:

```typescript
// packages/runtime/src/pty-screen-collector.ts
export const PTY_SCROLLBACK_ROWS = 10_000; // default ≈10k rows

```

Higher values increase memory usage but preserve more session history for debugging and session restoration.

## Runtime‑Policy Retention

User-specific runtime configurations are persisted as JSON documents with enforced size limits.

### Policy Document Constraints

In [`packages/storage/src/runtime-policy/policy-document.ts`](https://github.com/apache/maka/blob/main/packages/storage/src/runtime-policy/policy-document.ts), two mechanisms govern retention:

```typescript
// packages/storage/src/runtime-policy/policy-document.ts
export const POLICY_DOCUMENT_MAX_BYTES = 1_048_576; // 1 MiB ceiling

export function policySnapshot(document: RuntimePolicyDocument): RuntimePolicySnapshot {
  return deepFreeze({
    revision: document.revision,
    policy: structuredClone(document.policy),
  });
}

```

**Policy retention rules:**

- **`POLICY_DOCUMENT_MAX_BYTES`** — maximum serialized policy size; violations trigger `invalid_policy_input` errors
- **`deepFreeze`** and **`structuredClone`** — ensure snapshot immutability and deep copying
- **`revision`** — monotonic counter enabling optimistic concurrency control

### Writing Policy Mutations

The policy store provides atomic updates through `openInteractiveRuntimePolicyStoresForWrite`:

```typescript
import { openInteractiveRuntimePolicyStoresForWrite } from '@maka/storage';

// Open a writable policy store for a given user lease
const policy = await openInteractiveRuntimePolicyStoresForWrite(userLease);

// Increase the memory retention budget to 2 GiB
await policy.commitMutation({
  operation: { kind: 'memory', value: { maxBytes: 2 * 1024 * 1024 * 1024 } },
});

```

The `commitMutation` call validates the resulting document against `POLICY_DOCUMENT_MAX_BYTES` before persisting.

## How the Retention Layers Interact

Mako's context management combines both mechanisms during session lifecycle operations:

| Layer | Retention control | Restoration behavior |
|-------|-----------------|-------------------|
| **Terminal output** | `PTY_SCROLLBACK_ROWS` row limit | Scroll-back buffer rehydrated if `historyTruncated` is `false` |
| **Runtime configuration** | `POLICY_DOCUMENT_MAX_BYTES` size limit | Latest policy snapshot retrieved via `policy.read(root)` |

When recovering from crashes, the dispatcher uses retained scroll-back state **and** the policy snapshot to reconstruct the exact runtime environment. This dual-layer approach separates **ephemeral output history** from **durable configuration state** while applying consistent size limits to both.

## Source Files and Their Roles

Understanding these files clarifies how retention policies are configured:

- **[`packages/runtime/src/pty-screen-collector.ts`](https://github.com/apache/maka/blob/main/packages/runtime/src/pty-screen-collector.ts)** — implements scroll-back retention logic and `PTY_SCROLLBACK_ROWS` constant
- **[`packages/storage/src/runtime-policy/policy-document.ts`](https://github.com/apache/maka/blob/main/packages/storage/src/runtime-policy/policy-document.ts)** — defines `POLICY_DOCUMENT_MAX_BYTES` and snapshot serialization
- **[`packages/storage/src/runtime-policy/coordinator.ts`](https://github.com/apache/maka/blob/main/packages/storage/src/runtime-policy/coordinator.ts)** — orchestrates policy reads, mutations, and atomic commits
- **[`packages/storage/src/sqlite-long-term-memory-store.ts`](https://github.com/apache/maka/blob/main/packages/storage/src/sqlite-long-term-memory-store.ts)** — enforces retention rules at the storage layer, rejecting policy-denied compaction operations

## Summary

- **Terminal scroll-back retention** caps history at `PTY_SCROLLBACK_ROWS` (10,000 rows default) via `trackScrollbackRetention` in [`pty-screen-collector.ts`](https://github.com/apache/maka/blob/main/pty-screen-collector.ts)
- **Runtime-policy retention** limits policy documents to `POLICY_DOCUMENT_MAX_BYTES` (1 MiB) with atomic updates through the policy store API
- **Configuration changes** require modifying exported constants or calling `commitMutation` with validated operations
- **Session restoration** depends on both layers: terminal state when un-truncated, plus the latest policy snapshot

## Frequently Asked Questions

### How do I increase the terminal scroll-back history limit?

Modify the `PTY_SCROLLBACK_ROWS` constant in [`packages/runtime/src/pty-screen-collector.ts`](https://github.com/apache/maka/blob/main/packages/runtime/src/pty-screen-collector.ts) to your desired row count, then rebuild the runtime package. Be aware that higher limits increase per-session memory consumption proportionally.

### What happens when a policy document exceeds `POLICY_DOCUMENT_MAX_BYTES`?

The policy store rejects the mutation with an `invalid_policy_input` error before any write occurs. The existing policy remains unchanged, ensuring atomicity. Reduce document size by removing unused fields or compressing large values.

### Can retention policies be configured per-user rather than globally?

Yes. While `PTY_SCROLLBACK_ROWS` is a global constant, runtime-policy retention is inherently per-user through the `openInteractiveRuntimePolicyStoresForWrite(userLease)` API. Each user lease maintains an isolated policy document subject to the same `POLICY_DOCUMENT_MAX_BYTES` limit.

### Where does enforcement occur if the SQLite storage layer rejects a retention operation?

[`packages/storage/src/sqlite-long-term-memory-store.ts`](https://github.com/apache/maka/blob/main/packages/storage/src/sqlite-long-term-memory-store.ts) implements the final enforcement point, throwing errors that propagate back through the coordinator. This prevents disk-level writes that would violate configured retention policies even when upper layers pass validation.