How the Auto-Improvement Scheduler Works in ai-memory: Session Review and Proposal Approval
The auto-improvement scheduler in akitaonrails/ai-memory runs a background tick loop that claims completed sessions, generates wiki edit proposals through a read-only LLM review, and either auto-approves them or leaves them pending based on the require_approval configuration.
The ai-memory project implements an audit-first background pipeline for continuously improving wiki documentation. The auto-improvement scheduler periodically inspects finished sessions, turns them into durable proposals, and applies or stages them according to operator-defined safety settings.
Auto-Improvement Scheduler Startup and Scope Watermarking
When the server starts via ai-memory serve, the function initialize_auto_improve_scheduler_scopes seeds a watermark for every workspace-project pair. This prevents historic sessions from being auto-reviewed on upgrade. The initialization logic lives in crates/ai-memory-consolidate/src/auto_improve_schedule.rs at lines 48–76.
The Auto-Improvement Scheduler Tick Loop
Each periodic invocation of run_auto_improve_scheduler_tick (defined in auto_improve_schedule.rs at lines 124–166) executes a strict nine-step sequence. The scheduler is strictly separated from the approval logic: disabling the scheduler does not force manual approvals, and enabling manual approval does not stop the scheduler from running.
- Reads all scopes.
- Ensures scheduler state exists for each scope.
- Queries
auto_improve_candidate_sessionsfor new completed sessions, respectingmin_session_age_secsandmax_sessions_per_tick. - Claims each candidate atomically via
claim_auto_improve_scheduler_session. - Invokes the read-only reviewer
run_auto_improve_review. - Converts the review report into
NewAutoImproveProposals throughscheduled_auto_improve_new_proposals. - Stages the proposals in the store via
stage_auto_improve_run_for_owner. - Writes a side-car markdown file for each staged proposal via
write_auto_improve_sidecar. - If
require_approvalisfalse, callsWiki::approve_auto_improve_proposal; otherwise leaves proposals pending.
Querying and Claiming Candidate Sessions
On every tick, the scheduler queries auto_improve_candidate_sessions and claims each candidate atomically via claim_auto_improve_scheduler_session. This prevents concurrent ticks from reviewing the same session twice. The query also respects min_session_age_secs and max_sessions_per_tick to bound workload.
Reviewing Sessions with the Read-Only Pipeline
Claimed sessions are passed to run_auto_improve_review in crates/ai-memory-consolidate/src/auto_improve.rs at lines 94–121. This function is read-only: it inspects session observations, fetches recent wiki pages, builds an LLM prompt, calls the configured model, validates the response, and optionally runs an external eval gate (apply_eval_gate). It returns an AutoImproveReport containing validated proposals and any rejections. No database writes occur in this phase.
Staging Proposals and Writing Side-Car Files
Valid proposals are converted into NewAutoImproveProposal objects via scheduled_auto_improve_new_proposals. The scheduler then persists them by calling stage_auto_improve_run_for_owner, which stores the run in the pending-writes table (StageAutoImproveRun) alongside metadata such as provider, model, and configuration. A human-readable side-car markdown file is written to _pending/auto-improve/ via write_auto_improve_sidecar, creating an audit trail before any mutation reaches the wiki.
How the Auto-Improvement Scheduler Approves Proposals
Approval behavior is controlled by the require_approval flag in the [auto_improve] configuration section.
Auto-Approval vs Manual Approval
By default, require_approval is false. In this mode, the scheduler immediately calls Wiki::approve_auto_improve_proposal for each staged proposal. This wiki mutation path in crates/ai-memory-wiki/src/lib.rs enforces authentication, admission checks, and audit logging while preserving the actor name "auto_improve_scheduler_auto_approve".
When require_approval is set to true, proposals remain in the pending state. Operators can inspect, diff, approve, or reject them through the ai-memory pending-writes CLI commands.
# In .ai-memory.toml
[auto_improve]
require_approval = true
Conflict Handling and Deduplication
If the store already contains a pending proposal targeting the same page, the new proposal is skipped. The scheduler logs a warning (scheduled auto-improve proposal was not staged), increments the conflicts counter in the tick outcome, and surfaces the result as ApproveAutoImproveProposalResult::Conflict. This deduplication guard prevents overlapping edits from colliding in the pipeline.
Optional External Eval Gate
Before staging, proposals whose paths match eval.targets can be vetted by a user-provided external command inside run_auto_improve_review. Failures at this gate move the proposal to the rejected_candidates list, preventing it from ever reaching the pending-writes store.
Monitoring Tick Outcomes
After each tick, the scheduler returns a ScheduledAutoImproveTickOutcome (defined in auto_improve_schedule.rs at lines 94–107). The struct summarizes scopes processed, sessions reviewed, proposals staged, approvals executed, pending items left, conflicts encountered, skips due to store-level deduplication, and any errors. This data feeds the auto-improve-report telemetry and can be inspected via the CLI.
ai-memory auto-improve-report
You can also run the scheduler manually for testing or catch-up scenarios:
# Review the newest completed session
ai-memory auto-improve
# Review a specific session and auto-approve
ai-memory auto-improve --session-id 0123abcd
When operating in manual approval mode, use the pending-writes commands:
# List pending auto-improve proposals
ai-memory pending-writes list
# Show a diff for a specific proposal
ai-memory pending-writes diff <proposal-id>
# Approve a pending proposal manually
ai-memory pending-writes approve <proposal-id>
For programmatic access, an illustrative Rust call to the tick function looks like this:
let outcome = run_auto_improve_scheduler_tick(
&reader, &writer, &wiki, &llm, &settings
).await?;
println!("Reviewed {} sessions, {} approved", outcome.reviewed, outcome.approved);
Summary
- The auto-improvement scheduler is initialized at server startup with workspace-project watermarks to avoid re-processing historic sessions.
- Each tick claims completed sessions atomically, runs a read-only LLM review (
run_auto_improve_review), and stages proposals with audit side-cars before any wiki mutation occurs. - Proposals are auto-approved by default through
Wiki::approve_auto_improve_proposal, but settingrequire_approval = trueleaves them in the pending-writes store for human review. - The scheduler handles conflicts via store-level deduplication and supports an optional external eval gate to reject low-quality proposals before staging.
- Every tick produces a
ScheduledAutoImproveTickOutcomethat exposes detailed metrics for observability.
Frequently Asked Questions
What triggers the auto-improvement scheduler?
The scheduler is triggered by a background timer that invokes run_auto_improve_scheduler_tick while the ai-memory serve process is running. It does not run offline. You can also invoke review manually with the ai-memory auto-improve CLI command.
How can I disable automatic approval of proposals?
Set require_approval = true under the [auto_improve] table in your configuration file. This keeps all generated proposals in the pending state without stopping the scheduler from reviewing sessions and staging new proposals.
What happens if two proposals target the same wiki page?
The store enforces deduplication. If a pending proposal already exists for the target page, the new proposal is skipped and recorded as a conflict (ApproveAutoImproveProposalResult::Conflict). The scheduler increments its internal conflicts counter and continues processing other candidates.
Where are pending proposals stored before approval?
Staged proposals are stored in the StageAutoImproveRun pending-writes table and accompanied by a side-car markdown file under _pending/auto-improve/. This dual storage provides both a machine-readable queue and a human-readable audit trail for every proposed edit.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →