# How the Auto-Improvement Scheduler Works in ai-memory: A Deep Dive into Automated Session Review

> Discover how the ai-memory auto-improvement scheduler autonomously reviews sessions and suggests wiki edits. Learn more about this powerful background worker.

- Repository: [Fabio Akita/ai-memory](https://github.com/akitaonrails/ai-memory)
- Tags: deep-dive
- Published: 2026-08-28

---

**The auto-improvement scheduler is a server-side background worker that autonomously reviews newly finished sessions and proposes durable wiki edits, enabled by default when an LLM provider is configured.**

The `akitaonrails/ai-memory` system introduces an intelligent automation layer that transforms raw conversation sessions into structured, searchable knowledge. At the heart of this capability lies the **auto-improvement scheduler**, a Rust-based background worker that continuously processes completed sessions without manual intervention. This article explains exactly how this scheduler operates, from initialization through proposal staging, based on the actual source implementation.

## Scheduler Initialization and Scope Seeding

When you launch `ai-memory serve`, the scheduler automatically starts if an LLM provider is configured. The first critical step is **scope watermark initialization**, implemented in [`crates/ai-memory-consolidate/src/auto_improve_schedule.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-consolidate/src/auto_improve_schedule.rs) via the `initialize_auto_improve_scheduler_scopes` function.

This function seeds a per-scope watermark for every known workspace and project. This design guarantee ensures that **historical sessions are never auto-reviewed on upgrade**—only sessions completed after scheduler startup become candidates. The watermark mechanism prevents overwhelming the system with backlogged sessions and maintains predictable resource usage.

```bash

# Start the server — scheduler initializes automatically

ai-memory serve

```

## The Tick-Driven Processing Loop

The scheduler operates on a **non-overlapping tick model** defined by `[auto_improve.scheduler]` settings. Each tick, driven by `run_auto_improve_scheduler_tick` in [`crates/ai-memory-consolidate/src/auto_improve_schedule.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-consolidate/src/auto_improve_schedule.rs), processes all scopes sequentially.

Key timing parameters control this behavior:

- `interval_secs` — seconds between tick invocations (default: 3600)
- `max_sessions_per_tick` — limits throughput per cycle (default: 1)
- `min_session_age_secs` — minimum session maturity before consideration (default: 600)

Setting `interval_secs = 0` disables the scheduler entirely, while `enabled = false` in the same section prevents the background task from registering at startup.

## Candidate Selection and Atomic Claiming

For each scope during a tick, the scheduler queries `auto_improve_candidate_sessions` in [`crates/ai-memory-store/src/reader.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-store/src/reader.rs). This function returns **completed sessions** meeting three criteria:

1. Session age exceeds `min_session_age_secs`
2. Session has at least `min_observations` entries
3. Session duration meets `min_session_duration_secs` threshold

Selection respects `max_sessions_per_tick` to bound resource consumption. Once identified, a session must be **atomically claimed** via `claim_auto_improve_scheduler_session` in [`crates/ai-memory-store/src/writer.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-store/src/writer.rs). This claim writes a watermark entry to the auto-improve state table, enforcing **at-most-once review per session**—a critical safety invariant preventing duplicate LLM invocations and conflicting proposals.

## LLM Review and Structured Proposal Generation

The claimed session enters `run_auto_improve_review`, exposed from the `ai-memory-consolidate` crate. This function:

1. Loads the session page and recent observations
2. Retrieves relevant wiki context through the `ScopeResolver`
3. Constructs a **structured prompt** with strict output schema requirements
4. Invokes the configured LLM provider
5. Parses and validates returned JSON proposals

The prompt engineering ensures proposals conform to expected mutations: new page creation, slot updates, or relationship annotations. The reviewer explicitly **rejects any proposal that would rewrite a pinned page or invariant slot**, preserving editorial boundaries established by operators.

## Staging Proposals for Audit and Approval

Validated proposals flow through `StageAutoImproveRun` in `ai-memory-store`, which creates two artifacts:

- **Database rows** marking proposals as pending writes
- **Side-car markdown files** under `_pending/auto-improve/` for human-readable audit trails

This dual-write design supports both programmatic processing and operational transparency. The markdown files include provenance metadata: source session ID, confidence score, and generated reasoning.

## The Auto-Approval Decision Point

The `[auto_improve] require_approval` setting (default: `false`) determines final disposition:

| Setting | Behavior |
|--------|----------|
| `false` | Scheduler immediately calls `Wiki::apply_batch`, applying proposals through the standard mutation path |
| `true` | Proposals remain pending; operators approve via `ai-memory pending-writes approve <proposal-id>` |

Even with `require_approval = false`, all writes pass through `ApproveAutoImproveProposalResult` handling in the writer, preserving the **audit-first pipeline** used for manual `ai-memory auto-improve` commands. The scheduler runs under the internal `auto_improve` actor, ensuring auth enforcement and scope isolation through `ScopeResolver` helpers.

## Configuration Reference

The complete scheduler configuration in [`ai-memory.toml`](https://github.com/akitaonrails/ai-memory/blob/main/ai-memory.toml):

```toml
[auto_improve]
require_approval = false          # true → proposals stay pending

min_observations = 8
min_session_duration_secs = 120
min_confidence = 0.75

[auto_improve.scheduler]
enabled = true                    # false disables background review only

interval_secs = 3600              # 0 disables the scheduler

max_sessions_per_tick = 1
min_session_age_secs = 600

```

## Manual Invocation and Debugging

While the scheduler runs automatically, operators retain full control through CLI commands:

```bash

# Manually trigger review of newest unprocessed session

ai-memory auto-improve

# Review specific session by ID (bypasses watermark check)

ai-memory auto-improve --session-id 123e4567-e89b-12d3-a456-426614174000

# List pending proposals for a scope

ai-memory pending-writes list --scope workspace:myws project:myproj

# Approve pending proposal when require_approval = true

ai-memory pending-writes approve <proposal-id>

```

## Key Implementation Files

| File | Role |
|------|------|
| [`crates/ai-memory-consolidate/src/auto_improve_schedule.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-consolidate/src/auto_improve_schedule.rs) | Scheduler tick, initialization, and coordination |
| [`crates/ai-memory-store/src/reader.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-store/src/reader.rs) | `auto_improve_candidate_sessions` query |
| [`crates/ai-memory-store/src/writer.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-store/src/writer.rs) | Session claiming and proposal staging/approval |
| [`docs/auto-improvement-loop.md`](https://github.com/akitaonrails/ai-memory/blob/main/docs/auto-improvement-loop.md) | Design invariants and safety properties |
| [`docs/ARCHITECTURE.md`](https://github.com/akitaonrails/ai-memory/blob/main/docs/ARCHITECTURE.md) | System-wide data flow diagrams |

## Summary

- **The auto-improvement scheduler** is a background worker that transforms completed sessions into structured wiki proposals through automated LLM review.
- **Scope watermarks** prevent historical backlogs; atomic claims enforce at-most-once processing.
- **Dual-artifact staging** (database + markdown) provides both programmatic and human-auditable trails.
- **Configurable approval gates** balance automation with editorial control.
- **All mutations** pass through standard wiki admission pipelines, maintaining scope isolation and audit integrity.

## Frequently Asked Questions

### How do I disable the auto-improvement scheduler?

Set `enabled = false` in `[auto_improve.scheduler]` or set `interval_secs = 0`. The former prevents scheduler registration at startup; the latter allows registration but stops tick execution. Alternatively, omit LLM provider configuration—without it, the scheduler cannot start.

### What happens if two scheduler ticks overlap?

The implementation prevents tick overlap through internal locking in `run_auto_improve_scheduler_tick`. If a previous tick is still processing, the new tick skips execution and logs a warning. The `max_sessions_per_tick` limit further bounds execution time.

### Can I review what the scheduler proposed before it applies changes?

Yes. Set `require_approval = true` in `[auto_improve]`. Proposals then remain in pending state, visible through `ai-memory pending-writes list`, and require explicit `approve` invocation. The markdown files in `_pending/auto-improve/` show full proposal context.

### Why are some sessions never auto-reviewed?

Sessions may be excluded due to: insufficient observation count (below `min_observations`), short duration (below `min_session_duration_secs`), recent completion (below `min_session_age_secs`), or failure to meet confidence thresholds. Additionally, sessions completed before scheduler initialization are intentionally ignored via watermarking.