Summary
Heartbeat runs configured with isolatedSession=true and lightContext=true can still receive a large replay of prior heartbeat context. The docs describe isolatedSession: true as a "fresh session each run (no conversation history)", but the compiled prompt can include context-engine summaries and prior assistant/tool heartbeat outputs associated with the stable heartbeat session key.
On our production VPS this became a deterministic loop:
- heartbeat session key:
agent:trent:main:heartbeat
- configured model before mitigation:
ollama/nemotron-3-nano:30b
- estimated prompt: ~124,349 tokens
- prompt budget before reserve: ~111,616 tokens
- overflow: ~12,733 tokens
- messages reported by overflow diagnostic: 70
- auto-compaction attempts succeeded/retried, then the same precheck failed again
- after attempt 3/3, OpenClaw restarted the heartbeat session id and repeated on the next tick
In one 6-hour window on this deployment alone, we observed approximately 280 overflow prechecks and 70 restart cycles. The first visible crossing of the nemotron context limit was no later than 2026-05-17T22:15:27Z, and the pattern continued afterward until we mitigated locally by moving the heartbeat lane to a larger-context model and reducing cadence.
Repro config shape
A single agent heartbeat is enough when the model context window is smaller than the accumulated replay:
{
"agents": {
"list": [
{
"id": "trent",
"heartbeat": {
"every": "5m",
"model": "ollama/nemotron-3-nano:30b",
"isolatedSession": true,
"lightContext": true,
"target": "none"
}
}
]
}
}
The same class should reproduce with any model around a ~112K usable prompt window or smaller once enough heartbeat output has accumulated.
Documentation vs observed behavior
Docs say:
isolatedSession: true = "fresh session each run (no conversation history)"
lightContext: true = "only inject HEARTBEAT.md from bootstrap files"
Observed behavior:
isolatedSession=true creates a new session id, but not a fresh model context.
lightContext=true trims bootstrap files only; it does not stop context-engine/session replay of prior heartbeat summaries, assistant outputs, or tool results.
- Prior heartbeat no-change outputs can be promoted into future heartbeat context, increasing each future prompt.
Source-read root cause
From reading the installed 2026.5.18 dist source, the substrate appears to:
- derive a stable isolated heartbeat session key like
<base>:heartbeat
- call
resolveCronSession(... forceNew: true ...) to create a new session id
- then pass
SessionKey: runSessionKey, where runSessionKey is the stable isolated heartbeat session key
- pass
bootstrapContextMode="lightweight" for lightContext=true
So the session id is fresh, but context is still rebuilt against a stable heartbeat session key that can hydrate old heartbeat activity.
Evidence from compiled context
A failing heartbeat trajectory context.compiled event showed:
- system prompt original chars: 55,152
- messages retained in trajectory: 65
- original message array length: 70
- visible retained messages included:
- 6 user/context summaries
- 54 assistant heartbeat/no-change outputs
- 4 heartbeat tool results
- a truncation marker
- the replayed messages were prior heartbeat summaries and noisy no-change heartbeat replies, not current tick data
The actual heartbeat transcript .jsonl was absent after precheck failure; the evidence was in the trajectory file.
Expected behavior
When isolatedSession=true, a heartbeat tick should be truly bounded/fresh by default:
- no prior heartbeat assistant replies
- no prior heartbeat tool results
- no context-engine replay of previous heartbeat ticks
- include only current
HEARTBEAT.md, current time, pending system events/commitments, and explicitly configured bounded context
If preserving some heartbeat history is desired, it should be opt-in and bounded.
Actual behavior
Prior heartbeat activity is replayed into the next heartbeat prompt despite a fresh session id. Once the replay exceeds the model context window, reactive compaction/restart does not solve it because the same oversized context is regenerated on retry.
Impact
A quiet maintenance feature can become a load loop:
- repeated context-overflow prechecks
- repeated auto-compaction attempts
- repeated heartbeat session restarts
- degraded
/readyz from event-loop delay/utilization
- no useful heartbeat maintenance work completed
Suggested fix
Please add one of:
- A real ephemeral heartbeat mode that prevents any prior heartbeat output/context-engine replay from entering the next tick.
- Make
isolatedSession=true enforce no prior heartbeat history by default.
- Add an explicit bound knob such as
heartbeat.maxHistoryMessages, heartbeat.maxContextMessages, or heartbeat.replayHistory=false.
Also consider preventing notify=false / no-change heartbeat outputs from being promoted into future heartbeat context.
Summary
Heartbeat runs configured with
isolatedSession=trueandlightContext=truecan still receive a large replay of prior heartbeat context. The docs describeisolatedSession: trueas a "fresh session each run (no conversation history)", but the compiled prompt can include context-engine summaries and prior assistant/tool heartbeat outputs associated with the stable heartbeat session key.On our production VPS this became a deterministic loop:
agent:trent:main:heartbeatollama/nemotron-3-nano:30bIn one 6-hour window on this deployment alone, we observed approximately 280 overflow prechecks and 70 restart cycles. The first visible crossing of the nemotron context limit was no later than 2026-05-17T22:15:27Z, and the pattern continued afterward until we mitigated locally by moving the heartbeat lane to a larger-context model and reducing cadence.
Repro config shape
A single agent heartbeat is enough when the model context window is smaller than the accumulated replay:
{ "agents": { "list": [ { "id": "trent", "heartbeat": { "every": "5m", "model": "ollama/nemotron-3-nano:30b", "isolatedSession": true, "lightContext": true, "target": "none" } } ] } }The same class should reproduce with any model around a ~112K usable prompt window or smaller once enough heartbeat output has accumulated.
Documentation vs observed behavior
Docs say:
isolatedSession: true= "fresh session each run (no conversation history)"lightContext: true= "only inject HEARTBEAT.md from bootstrap files"Observed behavior:
isolatedSession=truecreates a new session id, but not a fresh model context.lightContext=truetrims bootstrap files only; it does not stop context-engine/session replay of prior heartbeat summaries, assistant outputs, or tool results.Source-read root cause
From reading the installed 2026.5.18 dist source, the substrate appears to:
<base>:heartbeatresolveCronSession(... forceNew: true ...)to create a new session idSessionKey: runSessionKey, whererunSessionKeyis the stable isolated heartbeat session keybootstrapContextMode="lightweight"forlightContext=trueSo the session id is fresh, but context is still rebuilt against a stable heartbeat session key that can hydrate old heartbeat activity.
Evidence from compiled context
A failing heartbeat trajectory
context.compiledevent showed:The actual heartbeat transcript .jsonl was absent after precheck failure; the evidence was in the trajectory file.
Expected behavior
When
isolatedSession=true, a heartbeat tick should be truly bounded/fresh by default:HEARTBEAT.md, current time, pending system events/commitments, and explicitly configured bounded contextIf preserving some heartbeat history is desired, it should be opt-in and bounded.
Actual behavior
Prior heartbeat activity is replayed into the next heartbeat prompt despite a fresh session id. Once the replay exceeds the model context window, reactive compaction/restart does not solve it because the same oversized context is regenerated on retry.
Impact
A quiet maintenance feature can become a load loop:
/readyzfrom event-loop delay/utilizationSuggested fix
Please add one of:
isolatedSession=trueenforce no prior heartbeat history by default.heartbeat.maxHistoryMessages,heartbeat.maxContextMessages, orheartbeat.replayHistory=false.Also consider preventing
notify=false/ no-change heartbeat outputs from being promoted into future heartbeat context.