feat: adaptive sleep advisory — memory-health-driven scheduling hints (Sprint F)#104
Merged
Merged
Conversation
ROADMAP Phase 2 adaptive sleep scheduling. MemForge is intentionally
designed without a built-in scheduler; this PR instead exposes a
read-only advisory that external orchestrators (cron, control plane,
dashboards) can use to decide when to trigger a sleep cycle.
MemoryManager.sleepAdvisory(agentId) evaluates five memory-health
signals and returns a structured recommendation:
- hot_backlog — unconsolidated hot_tier rows per agent
- contradiction_rate — reflections with open contradictions / total
reflections in the last 30 days
- revision_debt — warm rows below confidence threshold
- time_since_last_sleep — uses agents.last_sleep_cycle (v2.4)
- stability — inverse signal; clamps urgency down when the
agent's warm tier is highly graduated
(stable knowledge base → frequent sleep is
wasted LLM spend)
Overall urgency = max of the four active signals, then clamped to
'low' if the stability ceiling is exceeded. recommended = urgency
is 'medium' or 'high'.
Thresholds are tunable via env vars (SLEEP_ADVISORY_HOT_BACKLOG_*,
SLEEP_ADVISORY_CONTRADICTION_HIGH, SLEEP_ADVISORY_REVISION_DEBT_MEDIUM,
SLEEP_ADVISORY_MAX_AGE_HOURS, SLEEP_ADVISORY_STABILITY_CEILING) with
sensible defaults.
Public surfaces:
- GET /memory/:id/sleep/advisory (read-scoped)
- memforge_sleep_advisory MCP tool
- TS SDK: sleepAdvisory() on MemForgeClient + ResilientMemForgeClient
- Python SDK: sleep_advisory() on both clients
- OpenAPI route with full response schema
No schema migration. Existing columns (agents.last_sleep_cycle,
warm_tier.confidence, warm_tier.graduated, reflections.contradictions)
cover all signals.
Tests (tests/sleep-advisory.test.ts, 281 lines, 7 cases):
1. No activity → urgency 'none', recommended false.
2. 600 hot rows → hot_backlog urgency 'high'.
3. 2/10 reflections w/ contradictions (ratio 0.20) → urgency 'high'.
4. 60 low-confidence warm rows → revision_debt urgency 'medium'.
5. last_sleep_cycle 25h ago + activity → urgency 'medium'.
6. 85/100 graduated + 600 hot → stability ceiling clamps to 'low'.
7. Custom hotBacklogHigh=50 override → 60 hot rows → urgency 'high'.
Completes Phase 2 of the ROADMAP: namespaces (C), cold tier search
(D), memory budgeting (E), adaptive scheduling (F).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
ROADMAP Phase 2 adaptive sleep scheduling. Completes Phase 2.
MemForge is intentionally designed without a built-in scheduler (CLAUDE.md architectural rule). This PR instead exposes a read-only advisory that external orchestrators (cron, control plane, dashboards) can use to decide when to trigger a sleep cycle.
`MemoryManager.sleepAdvisory(agentId)` signals
Overall urgency = max of the four active signals, then clamped to `'low'` if stability ceiling exceeded. `recommended = urgency >= 'medium'`.
Thresholds (all tunable via env)
Public surfaces
No schema migration — all required columns already present.
Tests (`tests/sleep-advisory.test.ts`, 281 lines, 7 cases)
All use explicit timestamps, no sleeps.
Test plan
Phase 2 scorecard (closed out after this merge)