Skip to content

v5.0.0-beta.47

Choose a tag to compare

@github-actions github-actions released this 07 Sep 14:23
· 17 commits to dev since this release
b885f13

OMO 5.0.0-beta.47

✦ Aha moment! this is the memory release. nothing your agent learned gets dropped on shutdown anymore, Memorian keeps recalling straight through a 503, and every recollection now lands on screen as an aha moment. enjoy them.

engine unchanged: senpi 2026.9.7, same as beta.46. this one is all omo side, and most of it is the memory subsystem. i went looking for why memory felt thinner than the number of sessions said it should, and found it.

🧠 memory

the journal you wrote this session actually gets flushed now. (#7899, closes #7889)
the shutdown drain has a fixed 1.5 s budget, and the only durable step in it, journal-flush, ran last. before it, the drain awaited the Memorian judge, the gate and the facts children, and whenever one of those was sitting inside a provider retry chain the budget was gone before the flush was even attempted. i measured it on one host: 199 starvation events across 78 sessions, journal-flush skipped in 191 of them, and 183 came from ordinary omo.jsonc hot-reloads. one shared-config edit was silently dropping the journal of every open session at once. that is not a shutdown edge case, that is memory loss during normal use. the flush now runs first, before any pre-drain await, same deadline, no budget increase. and if it still gets skipped or aborted, you get memory shutdown drain skipped the journal flush at error level instead of a warning that nobody greps for.

Memorian reads your eval cells and your long shell commands now. (#7895)
the lexical planner never read eval code, and it threw away any shell command over 120 characters whole. if you live in eval, the judge basically never fired for you. it now harvests terms from eval code and summary arguments and from commands of any length, and reserves two newest-first, path-preferring query slots for tool terms, so one filename in a cell can surface a memory even when your prompt already owns both default slots.

  • late-judge salvage: nudges the judge already accepted before its deadline are delivered instead of dropped. tool-call-launched judges get a 90 s deadline (was 45 s, judge p90 was 44 s, you can see why).
  • a deadline is not a failure anymore. a judge that runs out of time with zero accepted nudges is dropped (cause deadline), so the red "Memorian gate failed - deadline" notice is gone for that case. 44 zero-token deadline aborts in 36 h on one host were rendering as failures. real provider breakage still shows as child_failed.
  • run retention: every judge run writes outcome.json. run dirs are pruned after 7 days, 30 when nudged, failed or dropped, throttled hourly.

the judge and the facts child ride your quick-category fallback chain. (#7907 fixes #7904, #7911)
both children were launched with only the primary model of quick and modelFallback: false. one 503 server_is_overloaded on that rung and the run was over, with the rungs you configured sitting unused in an array. they now receive the category's own chain (selectedModel + fallbackModels) and senpi rotates rungs mid-turn the same way it does for task subagents and the main session. a run fails only when the whole chain is exhausted. when fallbacks exist the same-model retry budget is capped at one, otherwise a two-rung chain could never be exercised inside the 90 s deadline. the beyond-category ladder stays refused: the judge is still pinned to quick, it just gets to use all of quick.

and the record tells the truth about which model answered. (#7911)
the gate entry, the nudged/empty result, the failure record and outcome.json now name the rung that actually produced the verdict, not the launch primary.

recollections look like recollections. (#7906)
a Memorian nudge used to read like third-party bookkeeping: Memorian nudged · <hint>, muted, with a via steer line. it now renders as ✦ Aha moment! / just remembered: <hint> (also remembered: for a second one) in the agent's own voice. the delivery route stays in the record for forensics but is gone from the screen, and the "hint, not current state" caveat moved to the expanded view. this is the one you will notice first.

known memory issue, not fixed in this release: #7912. the reflection scheduler never reclaims an active.lock whose launcher is dead when a retired run dir with the same id shadows it, so pending.json grows without bound and reflection/dream runs stop launching. if your runtime/reflection/active.lock names a dead pid, delete it once. the proper fix is tracked there.

🔁 DAG runs survive a desktop host restart (#7905)

a DAG run paused for its host's shutdown stayed paused forever if the successor host resumed the session while the predecessor was still exiting. that is the normal shape of an OmO Desktop RPC restart, so every desktop-hosted run that lived through a restart was stuck, and the desktop's "will be claimed and resumed automatically" prompt was lying. attach now arms a lease watch on the previous holder pid and re-runs recovery (claim, reconcile, reschedule) the moment it exits, in the same session, no second session_start. detach, pauseForShutdown and dispose cancel the watches.

🔒 ulw-loop toolkit: no lost updates, no silent shared scope (#7908, #7913)

  • cross-process state lock. every mutating CLI command (create-goals, record-evidence, checkpoint, ...) takes an O_EXCL lock file carrying pid + a per-acquisition token. stale locks are reclaimed only when the owner pid is dead, release unlinks only its own token, and a waiter that cannot acquire fails closed with ULW_LOOP_LOCK_TIMEOUT instead of proceeding unlocked. before this, three parallel record-evidence calls landed 1 of 3 criteria in 4 of 4 rounds while every process exited 0 with ok: true.
  • fail-closed session scope. without --session-id and without a session env key the CLI fell back to the cwd-global .omo/ulw-loop/ root. from an eval kernel, which does not carry PI_SESSION_ID, the same session could read a stranger's plan. it refuses now, and the ulw-loop pointer omo-senpi injects carries --session-id so eval calls land in the right scope.
  • locked legacy-plan migration. the aggregate-objective migration no longer runs from inside a read. an unlocked read of a legacy plan fails with ULW_LOOP_MIGRATION_REQUIRED and names the recovery (run any mutating command once).

🎯 workflow pointers stop putting words in your mouth (#7910, for #7890)

skill-pointers matched workflow names anywhere in any input and injected "The user asked for ...". in a multi-session setup, a relayed status line or a quoted advisory that named a workflow re-armed the pointer in the recipient, and the ultrawork trigger had no word boundary. inline and fenced code plus already-injected pointer blocks are masked before the keyword test, the pointer text is conditional ("if the user of this session is asking to run X ... otherwise ignore"), and ultrawork / ulw match on word boundaries only. ulw-loop still arms, ulwfoo does not.

🪟 windows

  • OpenClaw's reply-listener daemon is identified through Win32_Process (PowerShell addressed via SystemRoot, not PATH), so it can be detected and stopped instead of being orphaned on the first status check. (#7885, thank you @LilMGenius)

known issues

  • #7914: lsp-daemon's spawnDaemonProcess launches the daemon through the compiled omo binary without BUN_BE_BUN=1, so an ensureDaemonRunning retry can boot a phantom agent session instead of a daemon. present on dev and in this release, fix in progress. if you see short sessions you did not start, omo doctor lists orphaned engines.
  • #7912: reflection reservation not reclaimed after a dead launcher (see memory above).
  • #7902: DAG reconcile fails never-started nodes as task_lost instead of re-admitting them.
npm i -g omo-ai@beta
bunx oh-my-openagent@5.0.0-beta.47 install
bunx lazycodex-ai@5.0.0-beta.47 install

try it and tell me what breaks. i will be here.


  • b885f13 Merge pull request #7915 from code-yeongyu/release/v5.0.0-beta.47-source-state
  • f52d0cb Merge pull request #7911 from code-yeongyu/fix/memory-child-chain-provenance
  • df30a8e Merge pull request #7913 from code-yeongyu/fix/ulw-loop-lock-ownership
  • af000e4 fix(ulw-loop): track held locks per async continuation and record tokens in lock fixtures
  • 306aa83 fix(ulw-loop): refuse the legacy aggregate-objective migration on read paths
  • 39c168e fix(ulw-loop): never reclaim a live owner's lock and release only an owned lock
  • c55d97d Merge remote-tracking branch 'origin/dev' into fix/memory-child-chain-provenance
  • 04282b3 Merge pull request #7910 from code-yeongyu/fix/skill-pointer-intent-honesty
  • f0dbd31 Merge branch 'lane/facts-chain' into fix/memory-child-chain-provenance
  • a67cb38 Merge branch 'lane/provenance' into fix/memory-child-chain-provenance
  • eb4f0b7 Merge pull request #7908 from code-yeongyu/fix/ulw-loop-state-integrity
  • 4714a3a Merge pull request #7907 from code-yeongyu/fix/memorian-judge-quick-chain-fallback
  • d4345c5 docs(ulw-loop): document the session-scope requirement and the cross-process state lock
  • 30b7168 fix(ulw-loop): refuse unscoped state instead of falling back to the shared root
  • 2449a15 fix(ulw-loop): serialize state mutations with a cross-process lock
  • b210521 Merge pull request #7906 from code-yeongyu/feat/memorian-aha-moment
  • 5e49066 Merge pull request #7905 from code-yeongyu/fix/dag-recovery-desktop-resume-20260907
  • b78afb5 feat(memory-core): reserve recall query slots for tool-argument terms
  • 7670696 Merge pull request #7899 from code-yeongyu/fix/shutdown-drain-journal-starvation
  • 6d40443 Merge pull request #7885 from LilMGenius/fix/windows-reply-listener-daemon-identity
  • ef2dfcc test(openclaw-core): identify the reply-listener daemon against real child processes
  • 2fbe869 fix(openclaw): identify the reply-listener daemon on Windows

Thank you to 2 community contributors:

  • @LilMGenius:
    • fix(openclaw): identify the reply-listener daemon on Windows
  • @sisyphus-dev-ai:
    • test(openclaw-core): identify the reply-listener daemon against real child processes
    • feat(memory-core): reserve recall query slots for tool-argument terms
    • Merge pull request #7915 from code-yeongyu/release/v5.0.0-beta.47-source-state