Files
HomeAgent/cmd/homed
JianFeeeee 1d843daf2a fix(guard): 心跳提前启动 + 首次同步写入 —— 启动竞态的 worker 侧根修
562ba6bd 修了 guard 侧(给旧 mtime 加启动宽限,不误杀),那只是防御。
**根因**在 worker 侧:心跳文件要等全部重型初始化完(原 main 尾部)才
首写,且首次写是异步(在 goroutine 里,与多模态空间/知识库重建竞争
调度)。停机 >30s 后重启时 mtime 停在上一代 worker,guard 的 5s ticker
先到就 SIGKILL。

两层独立生效:
  worker 侧(本提交,治本):dataDir 一确定就启动心跳,首次写同步
  guard 侧(562ba6bd,防御):保留启动宽限期容忍旧 mtime

## 改动

- main.go:startHeartbeat 从尾部(190)移到 dataDir 解析后(54),
  用 context.Background()(心跳生命周期=进程,与 agent ctx 解耦)。
- bootstrap.go:startHeartbeat 首次 writeHB() 提到 goroutine 之外
  同步执行——返回前 mtime 必已变新,main 往下做慢事之前 guard 看到的
  是新心跳。

## 判据(TestHeartbeatFirstWriteSynchronous,变异测试通过)

  (a) 返回后立即查 mtime:必须是新的(同步首写),不许等到第一个 tick
      首写移回 goroutine(异步)→ (a) 当场 FAIL,已实测
  (b) 5s 后 mtime 再变(ticker 在跑)
  (c) stop() 后不再更新(hbStop 生效,不泄漏 goroutine)

判据覆盖完整生命周期:启动即新 → 周期更新 → 停止即停。

cmd/homed 包全量测试通过;全仓生产编译 GREEN。
2026-10-12 19:32:04 +08:00
..