NVIDIA / NVIDIA/NemoClaw

Configured OpenClaw heartbeat interval is lost during managed rebuild

Open
#10,244 2 comments 0 reactions 1 assignee Claimed by @Dreamstick9 View on GitHub
area: onboarding integration: openclaw
Dominant language
TypeScript
Stars
22.5k
Forks
3.1k
Avg merge
1d 1h
Merged PRs (30d)
715

Description

## Investigation summary

- `NEMOCLAW_AGENT_HEARTBEAT_EVERY=2m` reaches the managed startup profile, configuration environment, and `generate-openclaw-config.mts`.
- The generated `agents.defaults.heartbeat.every` is `2m`; OpenClaw 2026.7.1 resolves that exact config to 120000 ms.
- During state restore, `mergeOpenClawRestoredConfig()` overlays the backed-up `agents` tree and re-owns only `agents.defaults.model.primary`.
- A backup with no heartbeat or an older interval can therefore replace the freshly generated profile-owned heartbeat during rebuild.
- Direct generation tests cover the input but no lifecycle test binds the startup profile through state restore to the effective OpenClaw interval.

## Description

The documented OpenClaw heartbeat interval is not preserved across NemoClaw's managed state-restore path. A sandbox configured with `NEMOCLAW_AGENT_HEARTBEAT_EVERY=2m` can run OpenClaw with its 30-minute default after a supported rebuild or reconciliation restores an older `openclaw.json`.

The fresh managed-startup configuration must own `agents.defaults.heartbeat`, including configured presence or intentional absence, while the remaining durable `agents` settings continue to restore from the backup.

This is a defect in the supported heartbeat behavior established by #2880 and #3158. It does not change the heartbeat interface or add a new product surface.

## Reproduction steps

1. Onboard an OpenClaw sandbox with `NEMOCLAW_AGENT_HEARTBEAT_EVERY=2m`.
2. Confirm the startup profile and freshly generated `openclaw.json` contain `agents.defaults.heartbeat.every = "2m"`.
3. Preserve an older state snapshot whose `agents.defaults.heartbeat` is absent or set to another interval.
4. Run the supported rebuild/state-restore path.
5. Inspect the restored `openclaw.json` and the gateway's `heartbeat: started` record.

Current result: the backup's heartbeat state wins and OpenClaw can report `intervalMs=1800000`.

Expected result: the fresh profile wins and OpenClaw reports `intervalMs=120000`; the value survives supported rebuild, restart, and config reconciliation.

## Acceptance criteria

- A focused merge regression proves a backup with an absent, default, or different heartbeat cannot replace a fresh `2m` heartbeat.
- The fresh config also owns intentional heartbeat absence so a stale backup cannot re-enable it.
- Unrelated durable `agents` settings still restore.
- Managed-image lifecycle evidence binds the startup profile receipt to the generated config and OpenClaw's effective 120000 ms interval.
- Supported rebuild and restart retain the same effective interval and config-integrity hash.
- A first heartbeat can run within the configured interval's declared bound.
- No credential, policy, channel, MCP, or provider ownership rule is weakened.

## State and security boundaries

- Fresh profile `2m`, backup absent/different: fresh heartbeat must win.
- Fresh profile omits heartbeat, backup has a value: fresh omission must win.
- Malformed heartbeat input: existing pre-mutation validation must continue to reject it.
- Restore failure: the existing fail-closed restore and rollback behavior remains unchanged.
- The change is limited to ownership of the non-secret heartbeat subtree in the OpenClaw config merger.

## Environment

- Reproduced consumer version: NemoClaw `5ee38b5d555e5d59fce9570e623d2f09071075c1` (`v0.0.113-102-g5ee38b5d5`)
- Current `main` checked: `41bb231dabdd8f2305abb985e80ff0e2ba09c28e`
- Managed OpenClaw package: `2026.7.1`
- OpenShell-managed Docker sandbox

## Debug output

Sanitized runtime evidence reports `heartbeat: started` with `intervalMs=1800000` despite the documented `2m` onboarding input. Source-level reproduction isolates the first overwrite to the selective `openclaw.json` state merger. No credentials, endpoints, sandbox identifiers, or raw configuration are included.

## Non-goals

- Changing the public heartbeat environment variables or their format.
- Changing Remy's separate behavior of restarting its gateway from inside an MCP request.
- A host-local patch or credential change.

- [x] I confirmed this bug is reproducible
- [x] I searched existing issues and this is not a duplicate

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.