Skip to content

fix(bridge): start status heartbeat in --daemon mode - #2279

Closed
chiefmojo wants to merge 1 commit into
MemTensor:mainfrom
chiefmojo:fix/bridge-daemon-status-heartbeat
Closed

fix(bridge): start status heartbeat in --daemon mode#2279
chiefmojo wants to merge 1 commit into
MemTensor:mainfrom
chiefmojo:fix/bridge-daemon-status-heartbeat

Conversation

@chiefmojo

@chiefmojo chiefmojo commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

Fix: start the status heartbeat in --daemon mode

Closes #2278

Problem

#1998 made the Hermes launcher prefer dist/bridge.mjs, but bridge.mts only calls markConnected() / startHeartbeat() in its stdio (!args.daemon) branch. Daemon spawns therefore never refresh bridge-status.json; every reader applies the 20s staleness rule to a fossilized snapshot and reports "Hermes bridge heartbeat is stale" indefinitely — while RPC traffic keeps working, since it never touches status tracking.

Change

Mirrors the legacy bridge.cts daemon path: after the bind-retry loop succeeds, call

bridgeStatus?.markConnected();
bridgeHeartbeat = bridgeStatus?.startHeartbeat();

Both calls sit on the success path (after the loop's break;) so failure exits don't write a false "connected".

Plus a source-level regression guard test (tests/unit/bridge/bridge-daemon-heartbeat.test.ts), following the established pattern of bridge-startup-ordering.test.ts: the entry point is a top-level executable script, so runtime-testing two call sites doesn't justify refactoring it into an injectable function. The guard scopes to the daemon branch specifically — markConnected() in the stdio branch does not satisfy it.

Validation

cd apps/memos-local-plugin
npx vitest run tests/unit/bridge/ tests/unit/bridge-status.test.ts
# 8 files / 39 tests passed (includes the new regression guard,
# which fails on main without the fix)
npm run build   # dist/bridge.mjs emits both call pairs

The new test was verified RED against unpatched main (fails with "daemon branch never calls markConnected()") and GREEN with this patch.

PR MemTensor#1998 made the Python launcher prefer the pure-ESM dist/bridge.mjs
entry over dist/bridge.cjs, but bridge.mts only calls markConnected()/
startHeartbeat() in its stdio branch. Daemon spawns therefore never
refresh bridge-status.json; every reader applies the 20s staleness
rule to the fossilized snapshot and reports 'Hermes bridge heartbeat
is stale' indefinitely while RPC traffic keeps working. Mirror the
legacy bridge.cts daemon path, which always had both calls.

Pinned by a source-level regression guard alongside the existing
bridge-startup-ordering.test.ts.
@Memtensor-AI Memtensor-AI added area:plugin OpenClaw & Hermes status:in-progress Someone or AI is working on it | 人工或 AI 正在处理 labels Aug 23, 2026
@Memtensor-AI

Copy link
Copy Markdown
Collaborator

🤖 Open Code Review

Target: PR #2279
Task: e1d58e077b181e1f
Base: main
Head: fix/bridge-daemon-status-heartbeat

OpenCodeReview: Review skipped: no items were selected.

Generated by cloud-assistant via Open Code Review.

@Memtensor-AI

Copy link
Copy Markdown
Collaborator

⚠️ Automated Test Results: ENV ISSUE

The test environment encountered an issue that requires manual attention.

Details: Executor error: Command failed: git clone --depth 1 --branch fix/bridge-daemon-status-heartbeat git@github.com:chiefmojo/MemOS-contrib.git /data/test-workspaces/e1d58e077b181e1f/repo
Cloning into '/data/test-workspaces/e1d58e077b181e1f/repo'...
kex_exchange_identification: Connection closed by remote host
Connection closed by UNKNOWN port 65535
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
Branch: fix/bridge-daemon-status-heartbeat

@chiefmojo

Copy link
Copy Markdown
Contributor Author

Closing in favor of #2280 — it is the more complete upstream fix: dual-entry coverage (the .cts daemon branch has the same gap on main) plus heartbeat teardown in the shutdown handlers. Our version only patched .mts because our fork independently carries the .cts daemon-side calls.

Verified #2280's regression guard ourselves: RED on pristine main (both entries), GREEN on its own branch, mergeable state clean. Production evidence for the underlying bug is on #2278; fix confirmed live on our deployment.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:plugin OpenClaw & Hermes status:in-progress Someone or AI is working on it | 人工或 AI 正在处理

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] memos-local-plugin: --daemon entry never starts the status heartbeat — health reports "stale" forever while RPC works

3 participants