Hermes agent Version | Hermes agent 版本
0.16.0
Plugin Version | 插件版本
1.0.0
Operating System | 操作系统
ubuntu
System Specification | 系统配置
N100+12G RAM
Describe the bug | 问题描述
+### Summary
+In standalone mode (LocalStateBackend), the onTimerExpired callback in server.ts:1173 maps the pipeline's L2_schedule timer to offload-l2 instead of L2. This causes the long-term memory scene extraction (SceneExtractor.extract() → scene_blocks/*.md) to never run. Only scenes_processed stays 0 forever; seed-produced scenes in subdirectories are unaffected.
+
+The Redis (production) path works correctly because timer-scanner.ts:251 uses prefix matching and routes L2_schedule → L2.
+
+### Root Cause
+
+Two paths for handling the same L2_schedule timer, with inconsistent routing:
+
+Redis mode (correct):
+```
+timer-scanner.ts:251
- timerType.startsWith("L2") → taskType: "L2" → executeL2 → core.runL2WithStore → SceneExtractor ✓
+```
+Local mode (bug):
+```
+server.ts:1173
- suffix === "L2_schedule" ? "offload-l2" → executeOffloadL2 → OffloadTaskExecutor ✗
+```
+executeOffloadL2 expects offload storage (entries.jsonl, mmds, state.json) and returns in ~16ms when none exist — never calling SceneExtractor.extract().
To Reproduce | 复现步骤
+### Reproduction
+
+1. Install v1.0.0 on Hermes (standalone/deployMode=standalone)
+2. Send captures via POST /capture
+3. Wait for L1 → L2 timer chain
+4. Check /health → scansCompleted increments but scenes_processed stays 0
+5. scene_blocks/ directory remains empty
+6. Gateway logs show:
-
- [local-timer] Timer fired: :L2_schedule → enqueued offload-l2 task
- core.task.offload-l2 SPAN_END duration=16ms
-
+### Evidence
+
+- scenes_processed = 0 across all sessions (checkpoint.json)
+- Gateway logs confirm timer fires but routes to offload-l2 path
+- executeOffloadL2 completes in 16ms (no LLM call, no scene extraction)
+- The executeL2 handler and createL2Runner exist but are never invoked in standalone mode
+- OffloadTaskExecutor.executeOffloadL2 has zero references to SceneExtractor or scene_blocks/
+
+### Fix
+
+One-line change in src/gateway/server.ts:1173:
+
+diff +- taskType = suffix === "L2_schedule" ? "offload-l2" : suffix === "L1_idle" ? "offload-l1" : "L3"; ++ taskType = suffix === "L2_schedule" ? "L2" : suffix === "L1_idle" ? "L1" : "L3"; +
+
+This aligns the onTimerExpired callback with timer-scanner.ts:250-251's prefix-based routing. The offload system uses offload-l2: prefixed timer members (handled in the earlier branch of onTimerExpired), so this change does not affect offload behavior
Expected behavior | 预期行为
Fix
+One-line change in src/gateway/server.ts:1173:
+
+```diff
+- taskType = suffix === "L2_schedule" ? "offload-l2" : suffix === "L1_idle" ? "offload-l1" : "L3";
++ taskType = suffix === "L2_schedule" ? "L2" : suffix === "L1_idle" ? "L1" : "L3";
Error Logs / Screenshots | 报错日志/截图
No response
Additional context | 补充信息
No response
Hermes agent Version | Hermes agent 版本
0.16.0
Plugin Version | 插件版本
1.0.0
Operating System | 操作系统
ubuntu
System Specification | 系统配置
N100+12G RAM
Describe the bug | 问题描述
+### Summary
+In
standalonemode (LocalStateBackend), theonTimerExpiredcallback inserver.ts:1173maps the pipeline'sL2_scheduletimer tooffload-l2instead ofL2. This causes the long-term memory scene extraction (SceneExtractor.extract()→scene_blocks/*.md) to never run. Onlyscenes_processedstays 0 forever; seed-produced scenes in subdirectories are unaffected.+
+The Redis (production) path works correctly because
timer-scanner.ts:251uses prefix matching and routesL2_schedule→L2.+
+### Root Cause
+
+Two paths for handling the same
L2_scheduletimer, with inconsistent routing:+
+Redis mode (correct):
+```
+timer-scanner.ts:251
+```
+Local mode (bug):
+```
+server.ts:1173
+```
+
executeOffloadL2expects offload storage (entries.jsonl,mmds,state.json) and returns in ~16ms when none exist — never callingSceneExtractor.extract().To Reproduce | 复现步骤
+### Reproduction
+
+1. Install v1.0.0 on Hermes (standalone/deployMode=standalone)
+2. Send captures via
POST /capture+3. Wait for L1 → L2 timer chain
+4. Check
/health→scansCompletedincrements butscenes_processedstays 0+5.
scene_blocks/directory remains empty+6. Gateway logs show:
+### Evidence
+
+-
scenes_processed= 0 across all sessions (checkpoint.json)+- Gateway logs confirm timer fires but routes to
offload-l2path+-
executeOffloadL2completes in 16ms (no LLM call, no scene extraction)+- The
executeL2handler andcreateL2Runnerexist but are never invoked in standalone mode+-
OffloadTaskExecutor.executeOffloadL2has zero references toSceneExtractororscene_blocks/+
+### Fix
+
+One-line change in
src/gateway/server.ts:1173:+
+
diff +- taskType = suffix === "L2_schedule" ? "offload-l2" : suffix === "L1_idle" ? "offload-l1" : "L3"; ++ taskType = suffix === "L2_schedule" ? "L2" : suffix === "L1_idle" ? "L1" : "L3"; ++
+This aligns the
onTimerExpiredcallback withtimer-scanner.ts:250-251's prefix-based routing. The offload system usesoffload-l2:prefixed timer members (handled in the earlier branch ofonTimerExpired), so this change does not affect offload behaviorExpected behavior | 预期行为
Fix
+One-line change in
src/gateway/server.ts:1173:+
+```diff
+- taskType = suffix === "L2_schedule" ? "offload-l2" : suffix === "L1_idle" ? "offload-l1" : "L3";
++ taskType = suffix === "L2_schedule" ? "L2" : suffix === "L1_idle" ? "L1" : "L3";
Error Logs / Screenshots | 报错日志/截图
No response
Additional context | 补充信息
No response