Repository navigation
Releases: code-yeongyu/oh-my-openagent
Release list
v5.1.48
OmO Native stops waiting on a stalled turn-end subscriber after two seconds. Memory recovery remains retryable without treating the cancelled wait as a failed reflection run, and stall diagnostics identify the component and hook instead of only omo.js. Thanks to @floweredao for the report. (#11254, Part of #11249) (#11280)
Warm memory prompts avoid repeated git processes for HEAD and agreements. Committed agreement reads are cached by repository and full revision, and cache misses inspect only the ledger path. Standard file-backed HEADs resolve from stat-validated Git files, including packed refs and linked worktrees, with git fallback for unusual layouts. (#11216, part of #10707) (#11280)
Unchanged memory notices no longer yield a warm prompt to cold recall. Soul and agreement notices read their small atomic watermarks directly and skip lock acquisition only when valid state confirms nothing needs announcing or updating. Missing, malformed, or unreadable state is rechecked under the identity lock. Writers publish through unique, exclusively created temporary files, flush them before rename, and sync the directory where supported. (#11215, part of #10707) (#11280)
Memory notices survive a directory-sync failure after publication. Soul and agreement watermarks still flush before atomic rename and attempt directory sync, but a sync error after publication is logged without discarding that turn's announcement. Failed writes clean up their temporary files, repeated agreement ids use set comparison, and HEAD reads defer to git for worktree configuration. (#11234, part of #10707) (#11280)
Nested in-process tasks retain their original session tree. A child's own tasks now record the tree root and increasing depth, so nested delegation obeys max_depth instead of restarting at depth 1. The root session's own view now also covers its nested in-process descendants: the footer, /tasks, the default task_output list, and task_send and cancel. Process-mode descendants already appeared there. (#11226) (#11280)
Nested team members retain the original session tree. A child session leading a team now gives each member its own session as parent and the original tree root, with depth increasing from the lead. Persisted member ancestry is preserved when rebuilding a respawn. (#11229) (#11280)
The engine moves to senpi 2026.10.25-2: resuming a session interrupted mid-run no longer crashes, startup with many skills is fast again, long sessions keep their prompt cache when the context-budget reminder appears, and the per-request engine turn limit is off by default (#11240). With 748 skills, startup drops from 83.2 s to 1.4 s, fixing the slow start since 5.1.45 (#11245). In a long session that crossed the reminder at about 714k tokens of context, the request now writes 44k cache tokens instead of 758k. engineTurns.maxPerUserInput turns the turn limit back on; the 6-hour turn runtime cap still applies. Compaction finds a shorter safe tail when the summary would not fit. Kimi Code serves Kimi K3.1 Pro. A session that restarts or clears its queue no longer receives another session's queued messages twice. Claude subscription sessions run their SDK children in the session's project folder, so home-level Claude Code memory and settings no longer load into every session. MCP forms cancel instead of submitting empty answers when dismissed. Claude Code auto memory is never injected into Anthropic subscription sessions.
A ulw-research run cannot produce a reader-facing artifact against an undecided brief. The deliverable interview now also records a ## Fidelity block, and the new scripts/fidelity-policy.mjs registry turns it into the rules the CLI enforces: fact fill, fact verify, fact pairs, fact meaning-check, fact polish-apply and fact polish-diff refuse an unlocked brief with one fidelity_interview_incomplete defect and write nothing, each reading --brief (default $SESSION_DIR/brief.md), while collection keeps running; fact fill then refuses a derived row under derived numbers: none, evaluates the source floor live against each source's meta.json, binds a translation to its quote only under languages ... with translation beside, and omits a twice-failed sentence under fallback: omit. Off-table derived numbers or fallback values are usage errors instead of silently allowing; under any floor but standard a row with no source is refused; and the fill map records the brief's hash, so fact verify refuses an edition filled under a different brief (brief_changed) and re-checks every value against the current one. (#11166, closes #11009)
Fixed
-
Remove automatic
process_crashedtelemetry that used ordinary usage settings without separate crash consent. Starting a session no longer harvests operational crash records; manual/bugreports remain separate. (#11258) (#11280) -
75401cb Merge pull request #11166 from code-yeongyu/feat/11009-t19
-
40fe813 Merge pull request #11280 from code-yeongyu/batch/memsync-coord-13
-
91e090e chore(batch-13): canonical regen after the 5.1.47 release-state merge (pair a8428de970afabaa)
-
d8dd7c2 Merge remote-tracking branch 'origin/dev' into b13
-
08e9a95 Merge pull request #11282 from code-yeongyu/release/v5.1.47-source-state
-
68d4241 Merge remote-tracking branch 'origin/dev' into feat/11009-t19
-
3e6ad34 chore(batch-13): canonical regen on the merge result (pair 1c36c222100a40df)
-
eff0735 docs(changes): name the batch fragment after the batch PR (#11280)
-
95640d0 fix(ulw-research): fail closed on brief values, judge sourceless rows, and bind the brief into the fill map (Part of #11009)
-
c98c444 docs(changes): #11254's entry into the batch fragment
-
4924ad7 Merge remote-tracking branch 'origin/dev' into feat/11009-t19
-
8fc22fc docs(changes): fold car fragment #11258 into the batch fragment (fold-batch)
-
ea5778b docs(changes): batch #13 car entries as the batch fragment; CHANGELOG.md unchanged vs dev
-
fbf6544 fix(memory): isolate reconcile callers from observer cancellation
-
6a057cc fix(telemetry): stop sending automatic process_crashed without crash consent
-
7e3f4f1 chore(changelog): move the #11166 entry into a changes/unreleased fragment
-
18182ca Merge remote-tracking branch 'origin/dev' into feat/11009-t19
-
06e137a docs: link bounded-settle fix in changelog
-
ed7d503 fix(memory): bound and identify settled observers
-
40cc085 Merge remote-tracking branch 'origin/dev' into feat/11009-t19
-
fe2d042 chore(ulw-research): re-align #11166 to its base at feat/11009-t16
-
8e12c42 chore(ulw-research): align with the #11160 head record envelope and shared hashing (Part of #11009)
-
2107e56 chore(ulw-research): align with the #11160 head fidelity records and polish contract (Part of #11009)
-
b16f3d4 fix(memory): preserve published notices on sync errors
-
28928fd Merge remote-tracking branch 'origin/dev' into feat/11009-t19
-
af64398 Merge remote-tracking branch 'origin/dev' into fix/10732-nested-child-root
-
ab771ae chore(ulw-research): align with the #11160 head's text-only polish rule (Part of #11009)
-
e569cf2 fix(memory): guard optimistic watermark reads and publication
-
45575eb perf(memory): keep unchanged notices off async locks
-
5fa50c4 Merge remote-tracking branch 'origin/dev' into feat/11009-t19
-
ffc8381 Merge remote-tracking branch 'origin/dev' into perf/10707-memo-agreements-head
-
96ac1bb test(memory): harden HEAD and agreement regression fixtures
-
074620e docs(changelog): drop a stray merge marker (Part of #11009)
-
e5a9d65 refactor(ulw-research): import shared tables from their owners in the fidelity policy (Part of #11009)
-
1d67831 Merge remote-tracking branch origin/dev into feat/11009-t19
-
295a1f6 Merge remote-tracking branch 'origin/dev' into perf/10707-memo-agreements-head
-
3b179c4 test(memory): update recall budgets for filesystem HEAD
-
8bc2580 Merge remote-tr...
v5.1.47
- Memory path-state recovery and commit hooks now keep literal Git lookups working when global glob or case-insensitive pathspec modes are enabled (#11130, #11167). (batch #11187)
A user Stop pauses the workflow run it started instead of cancelling it. DAG nodes, workpool workers and task children hold where they are; a message to the paused run or Resume continues it from where it stopped. (#10808, fixes #6752) (batch #11187)
Concurrent file touches show each project memory nudge once. Project memory reads reserve the nudge before asynchronous loading, retry failed reads, and discard stale results after compaction or session changes. (#11165, addresses item 1 of #10927) (batch #11187)
A finished workflow run now shows as a finished run. When a workflow (DAG) run started from a session completes, including one that completes after recovery, the engine records the session's completion as a finished run instead of a plain reply (#11155). (batch #11187)
A finished ulw-execute plan now shows as a finished run. When this session's own ulw-execute work is marked completed, the engine records the session's completion as a finished run instead of a plain reply. Work finished by an earlier run, abandoned work, and another session's work are not counted (#11174). (batch #11187)
A completed ulw-loop plan now shows as a finished run. When this session's ulw-loop plan reaches its aggregate completion, the engine records the session's completion as a finished run instead of a plain reply. A plan that was already complete when the session started is not counted (#11175). (batch #11187)
CI exposes the lint ratchet as its own required-free status check. Pull requests, pushes and merge groups run Lint ratchet independently of the heavy-validation typecheck path. (#11128, thanks @Dante-dan) (batch #11187)
The 10k parked-backlog memory test now fails if it observed no entry reads. (#11164, part of #11091, thanks @Dante-dan) (batch #11187)
omo.dev/download no longer answers 404. Desktop builds link it from the reinstall screen and the .deb update pill; while the site's own download page is off, /download and /<locale>/download now redirect to the public beta download page at https://get.omo.dev/desktop/beta/. (#11270)
Gateway wakes, UI answers and releases reach a host session known only by its durable id. A multi-session host refuses any command that names no session, so a wake for a session read from disk or found by thread locate was lost with missing_session_id. The client now looks the session up on its host by durable id and routes the command; when no live session holds it, the delivery stays queued for the session's next start and omo thread report says the completion's wake did not reach it. (#11188, fixes #11185, part of #10995) (#11252)
Turning telemetry off through an environment variable no longer deletes summaries another session queued under a profile. A session whose OMO_PROFILE turns telemetry on could lose its queued usage summary when another session started with DO_NOT_TRACK and the base omo.json setting was off. Each summary queued from now on remembers the config it was recorded under and is judged by it when it is sent, resumed or cleaned up; summaries queued before the upgrade keep the old reading until they expire. (#11198) (#11202) (#11252)
The telemetry reference now states exactly which queued summaries an opt-out deletes and what the legacy rollups cleanup can and cannot remove. (#11181) (#11252)
senpi's on-demand memory report now shows OmO's task children and memory recall. With SENPI_MEMORY_REPORT=1, a report gains an omoTask section (resident task children, cached task records and their bytes, open event logs) and an omoRecall section (loaded memory corpora, their text bytes, the recall index's term arrays and dictionary size), so a large session's memory can be traced to these layers. Nothing is measured unless a report is taken. (#11178, part of #9442) (#11252)
Kimi K3.1 gets its own Sisyphus, Sisyphus-Junior and Atlas prompts. Kimi K3.1 Pro ids (k3.1-pro, kimi-k3.1-pro and their Highspeed versions) now route to separate copies of the K3 prompts instead of sharing K3's, and the Kimi Code id k3.1-pro gets a Kimi prompt at all. kimi-k3.1-pro maps to Kimi Code's k3.1-pro id. (#11197) (#11252)
Protocol-2 account storage has separate credential and pending-revocation namespaces. Legacy credential writes and deletes cannot overwrite either namespace; the origin key and native storage-error mappings stay shared. This is storage support for the protocol-2 rollout, not enrollment activation. (#11177, refs omo-service#628) (#11252)
A background task whose task host stays unreachable no longer comes back as a leftover session after recovery gives up. When a task child's reconnect timed out and its host answered only later, the stalled reconnect could retry after the session had already been closed and reopen it on the host, leaving a live session and its processes behind. The abandoned reconnect now stops retrying, while the parked child keeps its respawn and its single notice. (#11246, fixes #10925) (#11252)
Windows Codex commands no longer stop at a command syntax error. Generated command shims accept a quoted NODE_REPL_NODE_PATH in config.toml and also run when that setting or the config file is absent. Thanks to @fvegiard for the report and @LilMGenius for the fix. (#11222, fixes #7473) (#11252)
The ulw-research proofread lane returns edits that are checked before they land. The writing lane hands back polish-edits.json; fact polish-apply applies each edit only when it changes text nodes alone and keeps every number, hedge, qualifier, link, and claim id, fact polish-diff backstops hand edits, and fact pairs --changed-since sends every sentence polish rewrote back to the meaning readers. (#11160, part of #11009)
Changelog entries live in per-PR fragments, so pull requests stop conflicting on the changelogs. A pull request that changes what ships adds exactly one file, changes/unreleased/<pr-number>.md: the paragraph that used to go under ## [Unreleased] (or ### Fixed-style bullets), plus a <!-- changes-log: <path> --> block for each entry it used to prepend to changes.md or packages/<name>/changes.md. Only the release pull request edits those files: the release workflow writes every fragment into the release section and the logs, and deletes the fragments. What counts as shipped is unchanged, and bun script/changelog-fragments-cli.ts from-diff --base origin/dev --pr <n> converts a branch that still edits the changelogs. (#10477)
Fixed
v5.1.46
OmO Native init-deep committed mode no longer dead-ends. Committed mode now finishes through its own pull-request handoff instead of pointing at a skill that does not ship with OmO Native, and it reports how to finish by hand when no PR can be opened. Thanks to @HolisticDeveloper for the report and @surlymochan for the fix. (#11228, fixes #9686)
The stale-reflection-lock test leaves no background writer behind when removing its temporary root. Its teardown closes the memory wiring and awaits facts reconciliation and maintenance before removal, so a late lock publication cannot recreate the directory and make the temp-leak guard blame another test. (#11225)
ulw-research ships a Markdown block model for checking Markdown and post deliverables. It splits a Markdown report into headings, paragraphs, list items, table rows, code blocks and quotes with exact text offsets, and sorts sections with the same classifier as the HTML checks; an unclosed code fence is reported instead of passing silently, and no check uses it yet. The HTML checks now also treat a section headed exactly "Closing" as the closing section. (#11153, part of #11009)
ulw-research ships checked polish edits and a polish diff for research reports. Polish changes text nodes only: tags, every attribute, comments, and script/style/template content stay byte-identical, including attribute order and quoting. polish-apply rejects markup changes and edits that change a fact, number, unit, ticker, or required hedge, and checks cumulative edits against the original report; polish-diff applies the same rules to the whole report. An edit may not contain <, > or &, and may not touch a character reference even without them; both gates also compare the whole-document skeleton (every markup token and every character reference, byte for byte), so entities and markup are left untouched. Both gates refuse documents with markup the checker cannot model exactly. Markup changes require the full fidelity gates. Severities come from the defect registry. Nothing in the CLI calls them yet. (#11152, part of #11009)
Re-extracting a conversation no longer counts the same agreement correction again. Corrections are bound to validated user turns and recorded atomically with their replay receipts. Distinct turns on the same date still count separately; acknowledgement, drop and eviction retain replay history. Pending records from older versions use a documented agreement/date migration. (#11214, fixes #11191)
The LSP MCP server negotiates supported protocol versions. It preserves supported client versions and answers unsupported or missing versions with 2025-06-18, rather than claiming an arbitrary protocol revision. (#11208)
Skill MCP tool errors are reported as errors. Structured output and result metadata reach the caller, tool failures are not retried as connection failures, and plain content keeps its existing output format. (#11207)
The repository now has a security policy. SECURITY.md explains how to report a vulnerability privately through GitHub's Security tab, what to include, and when to expect triage and an acknowledgement; CONTRIBUTING.md links to it. Adapted from the policy proposed by @marklapointe in #10752. (#11221)
ulw-research can check that a report's sentences keep the meaning of their sources. It pairs each report sentence with the quote, claim or original text it rests on, and records drift only when two independent readers name the same kind of change; a single reader's flag is kept as a minor warning. A pair no reader judged, or a pair that needs the strong reader and only got the cheap one, is reported as unverified instead of passing as clean. Nothing in the CLI runs it yet. (#11151, part of #11009)
Skill MCP catalogs include every page. Tools, resources, and prompts follow opaque pagination cursors in order, with a clear error if a server exceeds 100 pages. (#11204)
omo update on Windows survives a package file that another process holds. When bun add -g fails with EPERM (NtSetInformationFile) because a file of the install is in use, omo update retries twice with a short backoff. If the file stays held, it names the file and the omo processes holding it, tells you to quit them and run omo update again, and keeps whatever version is installed, reinstalling the previous one only if the failed run left an unreadable install. (#10090, #11125)
A held abandoned test directory no longer fails a new run during preload. Cleanup retries through the shared tree remover, skips roots still held with EBUSY, EPERM, ENOTEMPTY or EACCES, and continues with the other abandoned roots. Unrelated filesystem errors still fail the run, and Bun's panic-only retry keeps its existing test-failure checks. (#11190, refs #11135 and #8990)
Usage summaries from older versions no longer stay on disk after an upgrade. Versions 5.1.34 to 5.1.44 kept session summaries in a rollups folder that nothing reads or sends any more. The first start after upgrading now deletes it, whether telemetry is on or off, and never follows a link out of that folder. With telemetry turned off in omo.json, a summary file that was cut short by a crash is deleted too. (#10234) (#11147) (batch #11168)
Computer-use cancellation retains engine crash diagnostics. Cancelled and timed-out calls keep their error code and carry the engine exit diagnostic as their cause. Capability-query permission failures remain structured tool results, hard engine diagnostics survive unrelated successful replies, and legacy launch refusals now share the structured record's exit-code and UTF-8 size rules. (#11150) Follow-up to #11086, part of #11073. (batch #11168)
Reflection and dream children share a machine-wide FIFO concurrency cap. The default is one running child across memory identities, configurable with memory.reflection.max_concurrent_runs. Queued runs retain their execution budget and remain protected from crash reconciliation until admitted. (#11161, fixes #11154) (batch #11168)
Memory reflection no longer stops for good when its host dies during a run. If the host died after a run had finished but before it was published, runtime/reflection/active.lock stayed held and every later reflection request only queued behind it until someone removed the file by hand. Now /reflect and every later turn settle a run whose launcher and publish claimant are both gone and whose outcome was recorded, so the queued request runs. A lock whose owner can't be checked is never reclaimed; it is reported with the next step, in the session and in omo doctor. Thanks to @Bearmancer for the report. (#10377, #10388, #10528) (batch #11168)
One bad memory entry no longer discards a whole reflection run, and credential-shaped prose is not a secret. Completion validation used to fail the entire run when any entry was refused (secret-like content, invalid frontmatter, a description over 1024 characters), so automatic reflection parked after a few runs. It now rewrites the run's branch as one commit without the refused entries, keeps the valid ones, and reports each dropped path with its reason (never the matched value); a run whose entries are all refused lands as no changes. The secret scanner and the pre-commit hook no longer flag assignments whose value only refers to a secret (process.env.X, $VAR, {{ slot }}, [FILTERED], the Bearer word, null/example literals), while a real value still matches. The dream's path_orphan finding now says when a file has no frontmatter, and its persona tells it to add a description in the same commit as the move instead of a bare git mv, which validation refused on every run. Thanks to @PGY0403 (#10385) and @floweredao (#1051...
v5.1.45
Reading the end of a long session takes 42 ms and 68 MB instead of 40 s and 1.8 GB. session_read, session_search and session_info page through OpenCode's message API instead of loading the whole session: on a 23,000-message session, session_read with limit: 2, from_end: true dropped from 39.6 s and 1,848 MB peak memory to 42 ms and 68 MB, and a search that runs out its 60-second timeout now stops reading when it returns, where it used to read another 228 MB in the background (#10738, #10741).
OmO's extension no longer carries an LSP engine it never runs. The native LSP tools and post-edit diagnostics already go through the packaged LSP daemon, but the formatter's import pulled lsp-core's whole in-process engine into omo.js; importing only the helpers it uses shrinks the extension by about 82 KB, with no change in behavior. (#10659)
Every session start reads about 33 KB less of omo.js: eleven memory slash commands and memory sync's device account load on first use (#10902, #10860). The commands (/memory, /remember, /init, /recompile, /memory-repository, /sleeptime, /reflect, /dream, /search, /facts, /agreements) still appear at startup with the same names, descriptions and hints; their handlers load from extensions/omo-memory-commands.js. The signed-in device account loads from extensions/omo-device-account.js the first time a session resolves its sync, and if that file cannot load, memory sync reports sync-unavailable with the reason instead of looking signed out.
ulw-research ships a fact ledger, a fidelity state file and a claim index for research reports. They give each research run a machine-readable record of its facts and verified claims; nothing in the CLI uses them yet. (#11046, part of #11009; batch #11148)
Child-task, workflow and workpool wake sources report kind children. (#11114, part of #10782)
An unreadable workpool store no longer drops or falsely clears the children wake source. (#11118, part of #10782)
The children wake source reads the workpool store once per snapshot. (#11124, part of #10782) (batch #11148)
Child results waiting in the wake queue keep the parent from reading as done. (#11115, part of #10782)
The wake-queue count can no longer cost a delivery receipt and is re-published per session generation. (#11121, part of #10782)
A receipt that throws no longer leaves the wake-queue count up. (#11122, part of #10782)
Delivery receipts are isolated from each other, on retire too, and no receipt error is dropped. (#11123, part of #10782) (batch #11148)
A wake-queue flush settles each receipt and the child count once, and a throwing onReceiptError no longer stops the rest. (#11137, part of #10782) (batch #11148)
Windows helper tree kills are guarded against recycled parent PIDs. A QA helper no longer stops an unrelated process tree that reused a parent's PID. (#11007)
A task that a quitting session suspended says why it is still running. Quitting the owning session parks every live child, but the parked record kept its bare running status with no reason, so a restart that never resumed that session read as a running task that nothing would ever move. The quit shutdown now records session_quit on the parked record, which task_output and the task snapshot present as "resuming (session quit)", and a later resume whose reconcile defers the revival replaces it with the deferral's own reason. (senpi#3493, #10533, thanks @Bearmancer)
A project's skills can no longer reach outside the project, and their MCP servers no longer get your whole environment. A skill link in a project that points outside it is refused, and the reason shows in the skill tool's result and in OpenCode; links into skill folders you configured yourself still work. MCP servers that come from a project's skills start with a small safe base (paths, home, temp, locale, CA paths) plus the variables they declare. When one asks for a variable it didn't get, the result names it with the exact /omo-mcp-env-grant command that saves the grant for that server declaration; only names are stored, in the same file the engine uses. Skills you installed yourself, including paths in your global OpenCode configuration, keep today's environment. Task discovery keeps nested reference documents out of skills and allows links between packages in the same repository. Unreadable or missing skills report their actual file error rather than a security block. Replaced or evicted grant commands expire, and reopening the server provides a fresh command when needed. (#10716)
Computer use explains a refused macOS launch context instead of reporting a closed engine. Initial activation and later restarts now report COMPUTER_LAUNCH_CONTEXT_REQUIRED with recovery instructions when the actual engine child refuses to start. Permission errors, desktop handover, and the native launch gate keep their existing behavior. (#11073, #11086)
Thread tools check that an RPC host is the one they selected before changing a session (#10712). The client proves the host's key with a challenge-response and attaches the selected session by its durable id on the same connection, so a host that reused a routing id cannot receive another session's mutation. A draining host answers with a retryable host_draining error instead of failing the call, and a change that took effect is never reported as failed.
The build now records which files each bundled artifact is built from. packages/omo-senpi/bundle-inputs.json lists every repo file the generators of the committed bundles read. The list is traced from the recipe itself, and CI checks that it is current. Merge tooling can now tell that a skill-only change leaves the bundles untouched (#11079, #11084).
A session with telemetry off clears leftover session summaries as soon as it starts. Summary files a crashed session left behind used to stay on disk until a later session with telemetry on picked them up. A session with telemetry off now deletes them at startup when omo.json turns telemetry off for their project; an opt-out set only through an environment variable such as DO_NOT_TRACK applies to that session alone and leaves other sessions' summaries in place. Turning telemetry off in omo.json takes effect on the very next turn instead of up to five seconds later. A summary whose project cannot be told apart is never sent. (#10234) (#10267) (batch #11148)
Session summaries survive a crash at any step and are never counted twice. Each summary window now has its own id, sent as the event id, and is written to a local pending file before it is sent; the file is deleted only after delivery is confirmed, and a later OmO start re-sends anything left over under the same id. A window left open by a killed process is sent once, only after that process is gone and its once-a-minute heartbeat has stopped for 5 minutes, so a sleeping laptop keeps its own window. The session sequence survives restarts and counts within a random per-run summary_epoch, and a session continued or recovered by another process starts a new one, so two processes writing one session never send the same (epoch, sequence) pair even when one of them is wrongly taken for dead, costs are added as whole 1/10,000 USD units (cost_1e4) so summaries and raw turns agree exactly, and dropped_events counts what had to be discarded after 14 days. telemetry.rawTurnSampleRate (or `OMO_TELEMETRY...
v5.1.44
The engine moves to senpi 2026.10.21-3: long 1M-context conversations stop re-writing their cached prefix, Anthropic subscription context is counted once, and "No credential slots available" no longer locks every account out (#10965). When context reduction trims a long conversation on a 1M window, the reduced prefix now stays identical and keeps its cache checkpoint, so each step writes only what changed. Anthropic subscription turns with internal SDK re-requests no longer double the context percentage or start compaction early, and a configured compaction model now summarizes while your session provider is healthy, overflow recovery included. The subscription lane is the only layer that picks its accounts, so one revoked or briefly rate-limited account no longer blocks the rest until you log in again. Every turn end says what happens next, a turn-end report names the hold your queued message released, the trailing "Anything else? (optional)" card is gone from clients without native questions, and moving a session between machines runs through one implementation. Forced recovery after a context overflow no longer picks the same compaction cut again when an invisible entry leads the session; an overflow still never moves a task to its next fallback model.
- 4846853 Merge pull request #10998 from code-yeongyu/release/v5.1.44-source-state
- db09ca1 docs(changelog): 5.1.44: a configured compaction model also covers overflow recovery
- a2595cb Merge pull request #10970 from code-yeongyu/fix/telemetry-spool-recovery-test-no-wallclock
- 5a98fb0 Merge remote-tracking branch 'origin/dev' into fix/telemetry-spool-recovery-test-no-wallclock
- 820426f Merge pull request #10984 from code-yeongyu/fix/env-isolation-test-windows
- 9aa2501 Merge remote-tracking branch 'origin/dev' into fix/telemetry-spool-recovery-test-no-wallclock
- 651620f chore(deps): regenerate the plugin bundles after merging dev
- 541c602 Merge pull request #10966 from code-yeongyu/fix/tests-never-replace-process-env
- 4cc2e16 Merge remote-tracking branch 'origin/dev' into fix/tests-never-replace-process-env
- bc9452c Merge pull request #10962 from code-yeongyu/test/10959-takeover-trace
- ecb7a0e Merge remote-tracking branch 'origin/dev' into test/10959-takeover-trace
- 3f7ec76 Merge remote-tracking branch 'origin/dev' into fix/tests-never-replace-process-env
- 7d79251 Merge remote-tracking branch 'origin/dev' into fix/telemetry-spool-recovery-test-no-wallclock
- 84bc5a1 test(telemetry-core): assert shutdown deadline order and cap, not wall-clock budgets
- 2220469 test(memory-core): takeover trace job fails on a failed run; every test phase is bounded
- 9528599 test(memory-core): writer child imports existsSync through the resilient fs module
- bcbad06 test(memory-core): the SIGKILL takeover test waits on events, not a 30 s budget
- 31382c3 test(memory-core): opt-in timeline for the SIGKILL takeover test, plus a 3-OS measurement workflow
bun add -g omo-aiv5.1.43
A session's first prompt no longer freezes a shared host while it reads what changed in memory (#10728). A session resumed a few hours after its last turn read the memory commits since then with one git diff-tree process per commit, all started at once. On a busy memory repository that was thousands of processes, and starting them blocked every session on the same host for 28 s with one session and 142 s with seven, while the finished ones piled up unreaped. The range is now read with one git log; the same notices come out, the longest block with seven sessions fell to 16 s, and the host's memory footprint during prompts fell from a median of 1,258 MB to 813 MB. (#10726)
Prompts stop freezing a shared host after every memory commit (#10731). Recall skips memory notes the conversation already mentions, and it rechecked the last 200 messages against every note again after each memory commit, one note at a time. On a 7,500-note memory that took 1 to 1.7 s per session per prompt, with every session on the host waiting. Earlier answers now carry over and only notes the commit added are checked, so a recheck takes about 6 ms and the first check about 0.2 s; with seven sessions and a commit every 20 s, the host's blocked time fell from 185 s to 28 s over four and a half minutes. The notes skipped are unchanged. (#10729)
A relaunch's first prompt no longer recompiles your memory. The compiled memory block and its size estimate are now saved by commit inside the memory repository's .git folder, never committed or synced, and read back on the next launch. On a 6,862-note memory this cut the memory step of a prompt from a median of about 178 ms to about 52 ms in the desktop app. A block built after a git read failed is used once and never saved. (#10674)
Anonymous usage stats now count how many accounts you have linked per provider. session_started reports, per provider kind, how many accounts the engine lists for it (the same list the app's account list shows: signed-in accounts and environment-variable slots), used or not, as capped counts only, never an account name, email, token or value (#10919).
The desktop app and omo login can share one device on a machine. A new hidden omo account command (show, adopt, token, export, forget) lets the desktop use the same OS-keychain sign-in the CLI writes, so a machine counts as one device for memory sync and only one process ever refreshes its tokens. Secrets pass only on stdin and stdout, a refused renewal (exit 5) names the service's refusal code so the desktop can say why the sign-in ended, and a locked OS keychain is reported as its own outcome (exit 7) instead of a generic failure. On Linux, where a locked Secret Service collection reads as empty, the default collection's lock state is read over D-Bus before any secret call (libsecret would otherwise ask the keyring to show an unlock prompt), a locked collection is reported (exit 7) instead of read, and when that check cannot answer (no gdbus on a minimal install, no Secret Service on the bus, a slow bus) the CLI prints one notice and uses libsecret directly as before, so login never depends on gdbus (#10658).
Memory sync can join a new device. omo sync enable turns memory sync on for the device and, if the account already syncs, asks a device that already syncs to approve it. omo sync approve on that device answers the request. Both screens show the same 6-digit code, and the new device is admitted only after the person confirms the codes match. A relay that swaps keys produces a different code and is refused. omo sync recover points to passkey recovery in the desktop app. (#10625, #10634)
A task started on a task host now records its own session id from the start (#10885). Before, the id stayed empty for every hosted task, so anything that looks up a parent task from a child's session, such as the desktop app's task tree or the cleanup when a task is cancelled, missed hosted tasks. The id was already in the host's answer when the session opened; it is now kept.
Anonymous usage stats now count the providers you signed into, not only the ones you configured. session_started counted only the providers in models.json, so a user who just signed into a subscription or added an API key showed zero providers. It now counts both, reports signed_in_provider_count and configured_provider_count separately, and still sends only the names of providers OmO ships (anything else is custom), never an account, key or credential (#10889).
A memory write recovers on its own after a crashed writer on Linux too. When a memory writer was killed mid-commit, the next write is meant to clear the git lock it left behind once the writer is proven dead. On Linux that check read other processes through /proc, and on a normal systemd login (or an SSH session, or a CI runner) some of the user's own processes cannot be read, so the lock was always kept and every write failed until /memory unlock. Memory's git commands now hold a kernel file lock that their git processes inherit, and the cleanup asks the kernel whether any of them is still running. A live writer's lock is still never removed. (#10604)
Resuming a session no longer asks git whether the commit it is pinned to still exists when that commit is the current HEAD. That saves up to two git processes on the first prompt after a resume. (#10707, #10854)
Each prompt reads your memory's git HEAD once instead of up to three times. The memory nudge, the soul notice and the session pin now share one read, which saves up to two git processes on every prompt. (#10707, #10855)
In a Bun project, lsp_diagnostics on a TypeScript directory typechecks it with bun check. A project with bun.lock, bun.lockb, bunfig.toml or a bun@ packageManager gets the errors bun check reports, which are the same errors as tsc 7. When the installed bun has a linter, bun lint diagnostics are added. For a project that formats with prettier, the Senpi formatter runs bun format --write instead of the prettier binary, but only once bun has proven it rewrites a file in place. Each command is used only after bun <command> --help succeeds in an empty directory, never when the project's own script of that name would run instead, and a probe that times out is retried rather than remembered as absent. Every other project keeps the language-server path unchanged (#10840, #10843).
A task-store admission no longer freezes the session while the disk is slow to flush (#10867, #10868). Registering a session's task store before a task host starts now does its durable write (fsync, rename, directory fsync) off the event loop, so a loaded Linux disk delays only that registration instead of every timer, socket and prompt of the process.
Memory no longer turns the assistant's own suggestion into "the user decided". Memory is now reference only: a remembered decision or approval counts only when its receipt quotes the user, and every memory write and extracted fact records who it came from (source: user, agent or inferred). A user receipt is kept only when the user's whole reply, sent right after the assistant's proposal, is a short explicit approval such as "yes", "ok", "delete it", "네" or "지워줘"; the receipt names the proposal it approved. Anything else, including a hedge, a question, an image-only message in between, or an older "ok", is stored as an agent suggestion, so the agent asks again instead of acting on memory. Thanks to @wuhaoyujerry for the report. (#10488, #10498)
Cancelling a task now also stops the tasks it started (#10824). Before, the cancelled task's session suspended its running children as if it could be resumed later, so they kept running tools on the task host with nobody able to collect them. A cancelled, lost or killed task now cancels its children when its session shuts down, and the same rule applies one level down. A live task's quit or reload still keeps its children so they can be collected on resume.
A task start is no longer refused when the model check can't finish on a busy machine. Before a task child starts, OmO checks that its model is available by listing models in a fresh CLI with a 20-second budget; on a heavily loaded machine that listing ran out of time twice and the start failed with catalog_probe_timed_out, even for a valid model. A check that times out now lets the start go ahead and is logged, a model list from the last 30 minutes is...
v5.1.42
Memory sync checks each new keyring entry without re-reading the chain before it. The client now uses the shared receiver's incremental entry point (omo-service #600, re-vendored), and the receiver moves along with the verified chain state. Appending one entry to a 1,000-entry chain used to hand the receiver all 1,006 entries again; it now hands it one, at any chain length. What the receiver refuses is unchanged, including a replayed or lower-seq entry. (#10694, fixes #10655)
The engine moves to senpi 2026.10.21-2: idle task hosts exit again, reopened sessions stop spending quota, and sessions share their prompt cache (#10893). A monitor watch no longer keeps every task shard host on the machine running, so idle hosts exit as designed. Reopening an unattended session no longer spends quota on goals or background events until you send input or choose Resume. Responses prompt-cache keys follow the model, instructions and tool schemas instead of the session, so new sessions and task children with the same prefix reuse one cache. A goal waiting on a subscription limit retries at the provider's reset time instead of hammering the spent account. On Windows, input sent while a turn is running no longer gets stuck or races through the whole fallback chain. Switching a long conversation to a smaller-context model while the current one is at its limit now applies at the next message, saving an API key over an OAuth login (or the reverse) replaces the credential instead of storing one that is never used, a busy command monitor is no longer muted after 200 lines a day, and every assistant reply records its timing (time to first token and generation rate).
OmO records when an answer says "tests pass" or "done" with nothing in the session behind it. When a turn's final answer says tests pass, a build or typecheck is clean, a feature already exists, or the work is done, OmO checks the session for a check that passed after the last code edit, and records in the session whether the claim is backed. It starts in shadow mode: nothing is shown to you or the agent and no turn is blocked or continued, because on a week of our own sessions most flags were still false positives. Setting the omo-senpi-claim-receipt-nudge flag turns on a short note under a flagged answer (once per message you send) and passes the flagged claims to a gate reviewer spawned afterwards. (#10785)
omo doctor --models shows which model every task category and agent runs, and exclude_models keeps a model out of all of them (#10763). The new doctor view prints, per category and agent, the model a spawn runs first, the retry chain in order, and each rung's source (built-in, omo.json, or the category an agent borrows) with why it does or does not run: excluded, no login, or not reached. It reads the same resolvers spawns use, and --json gives the same view to scripts. The new top-level exclude_models list (provider/model, a bare model id, or a * pattern such as "claude-fable-*") is honored by category and agent chains, memory children (the session model they would inherit included), the main session's model profile, explicit task pins, and task children respawned or resumed on a recorded model, including their recorded fallback chains. Before, no setting could stop a builtin rung from running; only logging out of its provider did (#10759).
Geeky becomes Obsessive. The two GPT lanes' display names are now Obsessive · Normal and Obsessive · Heavy, with one-line descriptions to match and a shared caution, NOT RECOMMENDED FOR WRITING OR EVERYDAY WORK., that the session-start notice renders in bold; the geeky-normal and geeky-heavy ids and the family they report stay unchanged, so a saved model_profile, a picker choice or a user overlay keeps resolving exactly as before. A model_profiles entry may set its own caution string, and one that replaces a builtin inherits its caution when it does not. (#10608, #10590)
Obsessive · Normal leads with GPT-6 Astra at medium. The geeky-normal model profile resolves GPT-6 Astra at medium on every GPT provider first, with its GPT-6.1 Sol Fast, GPT-6.1 Sol and GPT-5.6 Sol rungs kept as availability fallbacks; Obsessive · Heavy keeps Astra at high. (#10608, #10590)
Memory sync can verify and seal real batches. The sync engine now has a production verifier and sealer: each row another device appended is checked against this device's verified copy of the account chain, then opened with the epoch key the device holds, and only that memory's own notes reach it. Outgoing batches are encrypted, signed and linked the same way. Nothing uses this yet; the device sign-in that opens a session comes next. (#10625, #10627)
A signed-in device now reaches memory sync. Memory sync used to stay idle on every device, because nothing gave it the device's sign-in. It now reads the device omo login signed in, and the key pair that device registered, then opens the account's sync for that memory. A device that is signed in but has not joined the account's memory yet says so instead of reporting no sign-in. When the device signs out or is removed, sync closes and goes back to idle. (#10625, #10630)
A subtask whose category has no model left now finishes on the model your session runs. When every model in a delegated task's category is out (its usage limit is spent or its provider is not signed in), the task continues on your session's model in the same conversation, so tool calls it already finished are not run again. Before, it stopped with a usage-limit error even though your own model was working. The task's row, task_output and the completion notice say which model it ran on and why, for example parent-model:usage limit, resets 3:20am, and name any tool call the limit cut off, which never ran. Categories with a model that still works route exactly as before, and a session model on the same spent account still ends with the old error. Until the engine can limit this to spent or signed-out models, a task whose category models all fail for another reason, such as an overload, also continues on your session's model and says so (#10750, #10772).
Git worktrees of one repository can share the main checkout's memory. Set memory.auto_identity: "git" (for example in ~/.omo/omo.jsonc, so worktrees created outside the main checkout see it) and every linked worktree, including the ones Orca creates per agent, reads and writes the main checkout's memory instead of starting empty. The main checkout keeps its existing memory, sessions that are already bound keep theirs, and the default "path" leaves behavior unchanged. (#9659, #10047)
- 4d18b5e Merge pull request #10930 from code-yeongyu/release/v5.1.42-source-state
- 1c492a9 Merge pull request #10928 from code-yeongyu/fix/web-build-id-content-hash
- 7ca0c35 test(script): drop the compiled 10763 fragment from the command-string audit allowlist
- 738b7b1 docs(changelog): lead 5.1.42 with its measured optimization
- 5888e9f Merge pull request #10923 from code-yeongyu/test/10912-late-child-abort-signal
- d9309df docs(changelog): compile the unreleased change fragments into 5.1.42 and lead with the optimizations
- 45dc3e8 test(web): assert the inlined build id marker; note same-commit redeploys in the runbook
- cb52742 fix(web): build id from the commit so one /_next/static// path names one set of bytes
- ea4341e Merge pull request #10917 from code-yeongyu/test/10911-packed-sidecar-bounded-stages
- e7369e0 chore(deps): regenerate the plugin bundles after merging dev (bundle-train batch 1)
- da40a02 Merge pull request #10882 from code-yeongyu/batch/memsync-coord-1
- 59d133f Merge pull request #10909 from code-yeongyu/ci/web-deploy-skip-master
- 30d7ca2 docs(changelog): keep the batch #1 entries under [Unreleased] after the 5.1.41 cut
- 50b7e01 test(web): assert the exact deploy job condition
- 7c51aff ci(web): skip the production deploy on pushes to master
- f9de7ac Merge pull request #10907 from code-yeongyu/ci/10904-warm-python-before-eval-smoke
- 7bd5311 ci(publish): warm the kernel stdlib imports before the Windows eval smoke (#10904)
- 6ce160a chore(bundles): regenerate generated bundles for bundle-train batch #1 on current dev (bun 1.4.3)
- 2820b40 batch1: merge dev
- edcdccf chore(deps): regenerate the plugin bundles after merging dev
- 7d818ab Merge pull request #10886 from code-yeongyu/release/v5.1.41-source-state
- 1fce9cc Merge pull request #10880 from code-yeongyu/fix/10847-gatekeeper-window-clock
- f52b4a2 Merge pull request #10871 from code-yeongyu/fix/reload-cleanup-kill-wait
- 5131eae Merge remote-tracking branch 'origin/dev' into fix/10847-gatekeeper-window-clock
- 29b2eb9 chore(bundles): regenerate generated bundles for bundle-train batch #1 (bun 1.4.3)
- 9118704 test(script): count th...
v5.1.41
The engine moves to senpi 2026.10.21-1: engine hosts start faster and idle far more quietly, Claude subscriptions use the native 1M context again, and desktop threads are lighter (#10740). A new engine host starts about 0.1 s faster, and an idle engine host wakes 405 times per 90 s instead of 1,106. Current Claude subscription models (Fable 5, Sonnet 5, Haiku 5.5, Opus 4.7 and later) get their native 1M window back without asking for extra usage, and the Claude subscription lane runs Claude Code 2.1.306. Each desktop thread's engine supervisor starts from its own small program instead of the whole CLI, and messages and tool cards no longer keep duplicate copies (about 640 bytes per message and 2 KB per tool card). Models that models.dev marks deprecated stay available, labeled deprecated, instead of disappearing (GitHub Copilot Claude Opus 4.7, GPT-5.5 and GPT-5.4, Baseten Kimi K2 and others), and the model catalog is refreshed; some models get updated thinking levels (for example Nemotron 3 Ultra: off is now none). A message that was already delivered no longer stays listed under Steering, and with several accounts for one provider a usage limit stops failing turns once its reset has passed; a quota failure now says when it resets.
Memory sync refuses signatures under weak Ed25519 keys. Bun's WebCrypto accepts a signature made under a small-order public key, such as the identity key, for any message. The sync client now checks every key and signature it verifies itself, and refuses any keyring record that would bring a weak or malformed signing key into the account's keyring, including keys that appear only inside a fork-resolution's evidence. (#10743, fixes #10742)
Outside full access, computer use asks before it acts on your screen as a whole. Clicks, typing, key presses, scrolling, drags, pointer moves and holds aimed at the desktop or a display land on your real pointer and frontmost app, so they now need the same "Allow foreground computer control?" approval as foreground input; without it they fail with ControlRequired and nothing is sent. Input to one window in the background still needs no approval, and full access keeps working without a prompt, headless runs included. The macOS background check no longer moves your pointer back after you moved it, and a stopped session stays stopped when the desktop engine restarts. (#10788, #10790)
OmO counts how often you had to repeat a standing instruction (#10780, #10786). Rules like "never filter the monitor output" now live in system/agreements.md with a count. When you correct the agent on something an agreement already covers, the count goes up; after the third time (memory.agreements.needs_human_threshold) the agent is told the rule keeps being broken and you see a notice. /agreements lists them and lets you add your own, acknowledge one, or drop one; the agreements you add can only be changed by you. The design is inspired by dinobot by roach (PolyForm Noncommercial 1.0.0); no dinobot code was used.
The launcher deletes a legacy ~/.omo/credentials.json left by an intermediate sign-in build. The file held the device's private keys and account refresh material in plaintext, sometimes world-readable; upgrading removes it. Only the exact legacy shape is removed. (#10697, #10698)
Report a problem from inside OmO (#10546). /feedback (or /bug) sends a bug report or an idea to the OmO team in one step: your description plus your account, this device, versions, this conversation's recent messages, recent logs and your settings. Passwords, keys and tokens are removed first with the same redactor /share uses, your memory is never sent, and OMO_DISABLE_FEEDBACK=1 saves the report as a local file instead of uploading it. The desktop app's Report a problem dialog uses the same report.
A DAG node whose child dies on infrastructure is retried instead of taking its whole branch down. When a mass-ulw node's child stops answering its heartbeats or loses its host session, the node is now retried automatically, at most twice, with a backoff. Its dependents are skipped only if the retries fail too. Before, one starved wave failed and every later node was skipped (an overloaded machine skipped 54 of 61 nodes). Task failures and cancelled nodes behave as before, and the TUI and the desktop app share this behaviour (#10605, #10616).
Stopping a language server on Windows no longer raises a stray broken-pipe error. When an LSP server's pipe closed while OmO was shutting the server down, Windows could report the failed write after cleanup had already let go of it, and the EPIPE escaped as an unhandled error. Every pipe of a spawned language server now keeps an error handler for its whole life, so the failure is logged as ignored cleanup noise (#9601, #10725).
The frontend skill now covers HTML reports, figures and slides, and its stripe check catches square callouts. The skill now loads for any HTML, CSS or SVG made for visual output (a report printed to PDF, a figure, a diagram, a slide, an image for Notion or Slack), not only web UI. Its check-accent-stripes.ts linter fails a coloured bar along one side of a box whether the box is rounded or square, and a 2px-or-wider accent outline on a rounded card. Neutral hairlines, table rules, a blockquote's neutral rule, focus rings and input validation states stay allowed. The visualize skill runs the linter on every page before previewing or showing it (#10774, #10776).
ulw-research shows its report inline and checks a visual reproduction against the source (#10812). When the host can show an HTML page in the thread (show_html_page, html_render), the run ends with the report there, before the file paths, on every tier and even when the research was shortened; a built app or 3D scene shown inline no longer stands in for it. When the ask is to recreate something visual, such as a clip rebuilt in 3D, the run puts real frames of the source next to its own output at the same moments, writes down what differs, fixes the biggest gaps, and shows the side-by-side pairs in the report.
Changed
-
Combine macOS root-test shards and Codex/Senpi compatibility into one runner job, preserving their existing check names through Ubuntu status jobs. Full-matrix CI now requests two macOS runners per head instead of five, including unchanged native binary parity; fast paths skip the combined allocation (#10804).
-
CI: pull requests run the macOS and Windows legs only when a platform-specific path changes: any path a macOS/Windows-only CI step names (derived from the workflow), native crates, the launcher and platform packaging, the Windows Git Bash runtime, the Codex installer, platform-named sources, and the CI workflows. Pushes to
devand merge groups still run every OS, and therun-full-cilabel forces the full matrix on a pull request (#10856). (#10859) -
5b1bbe0 docs(changelog): compile the unreleased change fragments into 5.1.41
-
b2cbe05 Merge pull request #10875 from code-yeongyu/ci/platform-paths-followup
-
16bf941 Merge pull request #10877 from code-yeongyu/ci/fixture-no-bin-omo
-
edd8dec test(ci): native launcher fixture path no longer trips the /bin/omo audit (#10856)
-
2b48530 Merge pull request #10743 from code-yeongyu/fix/10742-memsync-weak-ed25519-keys
-
862664e Merge pull request #10859 from code-yeongyu/ci/pr-platform-path-matrix
-
cb23bfc Merge pull request #10833 from code-yeongyu/fix/10681-mock-audit-parse-only-matches
-
faa9e80 Merge pull request #10804 from code-yeongyu/ci/macos-combined-job
-
9ea7bb2 Merge remote-tracking branch 'origin/dev' into ci/macos-combined-job
-
949b363 docs(changelog): restore the paragraph break the dev merge dropped
-
6607685 Merge pull request #10786 from code-yeongyu/feat/agreement-violation-ledger
-
091df1a Merge pull request #10845 from code-yeongyu/fix/ulw-reload-cleanup-budget
-
d1aca9f Merge remote-tracking branch 'origin/dev' into HEAD
-
06949e1 Merge pull request #10834 from code-yeongyu/fix/10711-infra-retry-test-progress
-
ed586b4 test(audit): parse only mock.module candidates in lifecycle audit
-
e60f5e3 Merge remote-tracking branch 'origin/dev' into feat/agreement-violation-ledger
-
d98fe7a Merge pull request #10790 from code-yeongyu/fix/10788-cua-desktop-grant
-
eb6be62 Merge remote-tracking branch 'origin/dev' into feat/agreement-violation-ledger
-
59836e4 Merge pull request #10812 from code-yeongyu/feat/ulw-research-inline-report-compare
-
1e3033f Merge remote-tracking branch 'origin/dev' into feat/agreement-violat...
v5.1.40
5.1.39 was never published: its release run stopped before npm, so 5.1.40 is the next release after 5.1.38.
Onboarding saves only the facts you keep, and the TUI and the desktop share one completion flag. The facts you accept are written through memory's own write path, and finishing onboarding in either the TUI or the desktop marks it done for both. (#10506)
- 657a02e Merge pull request #10506 from code-yeongyu/feat/10481-onboarding-memory-apply
- 1056cb1 Merge pull request #10663 from code-yeongyu/fix/10660-posthog-packed-install-windows
- 3f67a8c Merge remote-tracking branch 'origin/dev' into feat/10481-onboarding-memory-apply
- e77a1d3 Merge pull request #10683 from code-yeongyu/release/v5.1.39-source-state
- cc47733 Merge pull request #10638 from code-yeongyu/ci/dev-push-runs-never-cancelled
- adc50dc Merge remote-tracking branch 'origin/dev' into feat/10481-onboarding-memory-apply
- add0b1c Merge remote-tracking branch 'origin/dev' into ci/dev-push-runs-never-cancelled
- f101145 Merge pull request #10600 from code-yeongyu/fix/10350-sync-crypto-lows
- 7b6708a Merge remote-tracking branch 'origin/dev' into feat/10481-onboarding-memory-apply
- 5e9cd7e Merge pull request #10584 from code-yeongyu/perf/recall-persisted-bm25-index
- 58ee699 Merge remote-tracking branch 'origin/dev' into perf/recall-persisted-bm25-index
- d6da044 docs: name the session-close behavior change and the inlined provider map (#10677 review)
- c40807c fix(memory): a later entry in a pull never changes an earlier entry's receiver verdict
- 7f0098b Merge remote-tracking branch 'origin/dev' into feat/10481-onboarding-memory-apply
- 7b7742f Merge pull request #10505 from code-yeongyu/feat/10480-onboarding-understanding
- 76f1f49 Merge remote-tracking branch 'origin/dev' into ci/dev-push-runs-never-cancelled
- 483c51e Merge remote-tracking branch 'origin/dev' into perf/recall-persisted-bm25-index
- 0187672 Merge remote-tracking branch 'origin/dev' into feat/10480-onboarding-understanding
- d159b26 Merge remote-tracking branch 'origin/dev' into fix/10350-sync-crypto-lows
- 61f1975 Merge pull request #10636 from code-yeongyu/fix/10632-skill-loader-hermetic-roots
- c938ebd Merge remote-tracking branch 'origin/dev' into fix/10632-skill-loader-hermetic-roots
- 048883f Merge pull request #10652 from code-yeongyu/fix/10650-scan-component-unwritable-agent-dir
- 8c184b7 Merge remote-tracking branch 'origin/dev' into feat/10480-onboarding-understanding
- 4c3901a Merge remote-tracking branch 'origin/dev' into fix/10650-scan-component-unwritable-agent-dir
- 85afdc2 Merge pull request #10657 from code-yeongyu/chore/regen-codex-install-bundle
- 394a9be Merge remote-tracking branch 'origin/dev' into feat/10480-onboarding-understanding
- a2c025d chore(omo-codex): regenerate the committed Codex installer bundle
- 694cc94 Merge remote-tracking branch 'origin/dev' into perf/recall-persisted-bm25-index
- 1aef9dc Merge remote-tracking branch 'origin/dev' into fix/10350-sync-crypto-lows
- 48c3f53 Merge pull request #10640 from code-yeongyu/perf/9915-lazy-posthog
- e60e316 fix(memory): run the sync receiver once per pull, not once per entry
- 1832be7 docs(changelog): scope the #10350 trust pin and receiver claims to what #10600 fixes
- df899f0 Merge pull request #10653 from code-yeongyu/docs/agents-md-types-node-pin
- 180ee97 Merge origin/dev into perf/9915-lazy-posthog
- 7d534f8 docs(agents): scope the tsconfig types rule to Bun-targeted packages and name both @types/node pins (#10653 review)
- 42eda2f docs(agents): the @types/node root devDependency is a resolution pin, not a tsconfig type (#10646)
- 499f4a4 test(#10650): make the agent dir unwritable with a regular file, not chmod 0o555, so the case holds on Windows
- 4afa1dc Merge pull request #10647 from code-yeongyu/fix/root-types-node-devdependency
- 15c6a19 Merge remote-tracking branch 'origin/dev' into fix/root-types-node-devdependency
- 5376221 Merge pull request #10622 from code-yeongyu/fix/memsync-10620-legacy-cycle-lows
- ec81b09 fix(build): declare @types/node as a root devDependency so the repo's own copy wins type resolution
- 9b8f43f Merge pull request #10618 from code-yeongyu/fix/10613-git-env-prefix
- 228da0a Merge remote-tracking branch 'origin/dev' into fix/10613-git-env-prefix
- 72d98d4 test(#10632): the hermetic home also pins the user skill roots, and skills-loader-core's runner loads it
- 92760d2 test(memory-core): drop the exclusion test no single gate check makes fail
- c486e0a Merge remote-tracking branch 'origin/dev' into perf/recall-persisted-bm25-index
- 4481f4e fix(memory-core): restore holds an exclusive gate over recall term-store saves
- ec9adf1 Merge remote-tracking branch 'origin/dev' into feat/10480-onboarding-understanding
- b54b8f0 Merge pull request #10496 from code-yeongyu/feat/10478-onboarding-scan-rpc
- 6b4491c Merge remote-tracking branch 'origin/dev' into perf/recall-persisted-bm25-index
- cd833ae Merge remote-tracking branch 'origin/dev' into fix/memsync-10620-legacy-cycle-lows
- e07e22d Merge remote-tracking branch 'origin/dev' into feat/10478-onboarding-scan-rpc
- 713c4f7 Merge pull request #10497 from code-yeongyu/feat/10479-engine-session-discovery
- 2d5262c Merge remote-tracking branch 'origin/dev' into perf/recall-persisted-bm25-index
- b670cc7 Merge remote-tracking branch 'origin/dev' into feat/10479-engine-session-discovery
- 9e4ceeb Merge pull request #10621 from code-yeongyu/fix/memsync-10611-recovery-head-descends
- ccdf076 chore(omo-codex): regenerate the Codex installer bundle for the git_master schema change (#10613)
- d3cc7fb fix(memory-core): wait for the recall store save before a test root is removed
- 4c44bc9 test(git-master): use a neutral env name in git_env_prefix fixtures (#10613)
- 4a7f19a Merge pull request #10599 from code-yeongyu/fix/10321-adoption-receipt-guard
- b28494d fix(memory-core): find the missing state dirs before mkdir so an EINTR retry cannot skip the parent fsync
- a57a53c docs(changelog): note unknown-key legacy adoption fix (#10622)
- 2ddf177 fix(memory-core): legacy cycle adoption skips keys the store never knew; tighten Loro resume tests
- 9baa1c9 Merge remote-tracking branch 'origin/dev' into fix/10321-adoption-receipt-guard
- ee24752 docs(changelog): note the git-master git_env_prefix restore (#10613)
- 06d32b4 Merge pull request #10598 from code-yeongyu/fix/memsync-10588-followups
- 6059418 docs(changelog): note descending-head recovery and created-dir fsync (#10621)
- 00a8e58 fix(memory-core): accept a keyring head that descends from our rotation; fsync created state dirs into their parents
- 15b7cad Merge remote-tracking branch 'origin/dev' into fix/10613-git-env-prefix
- b6230fc Merge pull request #10603 from code-yeongyu/fix/memsync-10450-recovery-durability
- 81ea4da docs(changelog): link the #10321 entry to PR #10599
- 447f667 fix(git-master): restore git_env_prefix on native and the forceful skill description (#10613)
- 1449fa2 test(git-master): RED tests for native git_env_prefix port (WIP for #10613 takeover)
- b8ebb81 docs(changelog): drop the claim about the deleted import guard (#10321)
- 88bf086 Merge branch dev into perf/recall-persisted-bm25-index
- 3113ad2 test(memory-core): drop the lexical withRegisterValues import guard
- 2e65dcf docs(changelog): link #10598 from the #10588 entry
- bcce104 Merge remote-tracking branch 'origin/dev' into feat/10479-engine-session-discovery
- 4daffc5 Merge remote-tracking branch 'origin/dev' into fix/memsync-10450-recovery-durability
- c8eb2bc Merge pull request #10549 from code-yeongyu/memsync/projection-pin
- 6c514d4 fix(memory): compare pin fsync call paths with forward slashes on Windows
- 9be5f91 fix(memory): name synced devices in production and read the range log once
- 51835c4 Merge pull request #10610 from code-yeongyu/fix/10609-omob-provenance-fixture-inode
- 3deb1bd docs(changelog): link #10584 from the recall entry
- 5318f8a test(omob): reinstall the fixture by rename so the stale-marker case always gets a new inode (#10609)
- c965355 Merge remote-tracking branch 'origin/dev' into fix/memsync-10450-recovery-durability
- 5e6fa92 Merge remote-tracking branch 'origin/dev' into feat/10479-engine-session-discovery
- cfcecfb Merge remote-tracking branch 'origin/dev' into perf/recall-persisted-bm25-index
- 82eac2d Merge remote-tracking branch 'origin/dev' into memsync/projection-pin
- ded23a5 Merge pull request #10386 from code-yeongyu/fix/category-shadow-lows
- 4f3bfdf docs(changelog): note the memory sync trust pin hardening (#10350)
- 3334959 docs(changelog): memory sync recovery write hold (#10603)
- fc1cb08 docs(changelog): note the #10321 adoption read-back fix
- 57eacd6 fix(memory-core): recovery releases the write hold only for its own stored rotation, durably
- ad3fded docs(changelog): note the #10588 sync engine crash-resume hardening
- 07019bf fix(memory): close the six crypto LOWs deferred from #10298
- c01707c fix(memory-core): keep captureOnDevice the only adoption commit path and read joined registers only in the header
- 97f0dda fix(memory-core): close the #10548 sync-engine review follow-ups
- 8e1ea75 docs(changelog): synced memory changes reach running sessions (#10549)
- a4adbfc feat(memory): show synced changes to running sessions
- 8351c19 Merge remote-tracking branch 'origin/dev' into fix/category-shadow-lows
- 0050ac4 Merge remote-tracking branch 'origin/dev' into feat/10479-engine-session-discovery
- 808e65c Merge pull request #10548 from code-yeongyu/memsync/sync-engine
- 54e8858 Merge pull request #10575 from code-yeongyu/fix/10419-nodeless-env
- 67dea2e Merge...
v5.1.38
5.1.37 was tagged but its publish stopped on Linux (the release binaries outgrew their size budget), so its main packages never reached npm; everything listed for it ships in this release. (#10566)
Release binaries may be up to 182 MiB. The per-platform size budget moves from 160 MiB to 182 MiB after measuring what grew: the Bun 1.4.3 runtime adds 9.5 MB to every binary and the senpi update about 1.25 MB, so linux-x64 reached 173.4 MB. Nothing was bundled by mistake. (#10566)
5.1.36 was prepared but never published; everything listed for it ships in this release. (#10552)
The engine moves to senpi 2026.10.19: a hung extension handler no longer freezes a session, and queued input survives a crash. An extension handler that never settles on a lifecycle event is named in the session after 60 s and released after 20 min, or at once on Esc or the turn deadline. Input queued with a client id is written to the session file before it is queued and delivered exactly once. The mouse wheel scrolls the transcript again while a question prompt is waiting, Alt+Q restores queued messages on WSL, and the /btw panel no longer repeats a running eval's output in the scrollback. Anthropic requests of 4096+ characters to api.anthropic.com are now sent gzip-compressed, as Claude Code does. (senpi#3650, senpi#3549, senpi#3604, senpi#3628, senpi#3649, senpi#3643, #10552)
Goals keep going while they make progress, and long sessions open and stay light (senpi 2026.10.18-1). A goal no longer stops after a fixed 150 automatic continuations; it stops only after 60 in a row with no new tool effect, todo change or message from a person, and says why and that any message resumes it. Opening a very large session on a shared host no longer stalls the other sessions, a reopened session keeps only its latest compaction window in memory (four of the largest local transcripts went from 1441 MB to 216 MB of live heap), and reading a very long history over RPC pages instead of dropping the connection. A Claude subscription from CLAUDE_CODE_OAUTH_TOKEN or an ambient Claude Code login now shows as a connected subscription, and a host daemon inherits every credential variable the engine reads. Provider accounts can be ordered, and grep starts 5 to 14 rg processes where it used to start 63 to 87. (#10280, #10509) The engine also fixes ChatGPT browser sign-in dead-ending on "State mismatch." when another session holds the callback port (senpi #3627), and a compiled engine now finds the Claude Code binary shipped beside its executable instead of failing the lookup (senpi #3640).
A client re-attaching to a retained session gets the full task snapshot again, and can pull it on demand. The task RPC bridge listens for session_resumed, which senpi fires when the first client re-attaches to a still-open session, and re-emits the complete omo.task.updated snapshot instead of waiting for the next store change to alter its fingerprint; a new omo.task.list request answers the same payload for the parent session it names. (#10016, #10122)
Memory recall's search index takes a quarter of the memory it did, and a memory write no longer rebuilds it. Every session that recalls memory keeps a search index of the whole memory. It stored each note's words as a separate table, so a memory of 6,406 notes cost about 231 MB per session, and each memory write threw the index away and rebuilt it, taking 3 to 11 seconds. Words are now numbered once and each note keeps a compact list of numbers that survives a memory write, so the same memory costs 55 MB and a write updates the index in about 16 ms. The notes found and their order are unchanged. (#10510, #10512)
A background task child follows its session when another client replaces it. A raw RPC client that issues new_session, switch_session or fork on a daemon child's routing handle moves that session to a new durable id and transcript; the child now observes the session_replaced record, re-stamps its record's session path and durable id, appends a replaced task event, and reattaches to the new transcript instead of the abandoned one. When the replacement stops a turn the child was running, the child ends interrupted with the reason and a task_send action, and the parent is notified because it did not ask for that stop (a parent's own interrupt stays silent); this needs a senpi that names the cause on agent_end (senpi#3357), and an older host keeps the previous error. (#10018, #10112)
unspecified-low tries GLM 5.3 before GPT. A user with Claude and Z.ai (or OpenCode Go) but no Xiaomi or xAI provider used to fall from Sonnet 5.5 straight to GPT-6.1 Sol once Sonnet was unavailable. The chain now has glm-5.3 at high thinking right after Grok 4.7 and ahead of the GPT rungs, so the order for users who hold MiMo or Grok is unchanged. (#10306, #10311)
omo --help no longer moves your OpenCode config before you start a session. On a fresh install --help (and --list-models / --list-tips) loads the omo extension, and its startup migration moved ~/.config/opencode/oh-my-openagent.json into ~/.omo/migration-backup-*, so a 4.19.x OpenCode plugin fell back to its defaults. The migration now runs only on launches that can start a session, and --help still lists omo's own flags. Thanks to @bluet for the report and @twotnguyen for #10433. (#10428, #10454)
Built, tested and released on Bun 1.4.3. CI, the release workflows and the devcontainer move from Bun 1.4.2 to 1.4.3, the current stable release, which fixes CVE-2026-48618 (TLS host names) and idle garbage collection in workers. (#10432)
OpenCode edition: Sisyphus names GPT-6.1 Sol and GPT-6 Luna as themselves. On gpt-6.1-sol (and its -fast, dashed and Venice gpt-61-sol ids) and on gpt-6-luna, the Sisyphus and Sisyphus-Junior GPT prompts introduced the model as "a GPT-family model"; they now say "GPT-6.1 Sol" and "GPT-6 Luna". (#10291, #10292)
Memory session shutdown waits for the work it started in the memory directory. Shutdown now waits, within its existing drain budget, for an in-flight repo maintenance pass and for the status refreshes started at bind and settle, all of which run git inside the identity directory. Before, they could still hold files open after shutdown returned; on Windows the next delete of that directory failed with EBUSY/EFAULT, which is how the memory pressure-dream test failed intermittently in CI. (#10154, #10312)
Oh My OpenAgent loads on OpenCode 2. OpenCode 2 refused the plugin with Plugin must export a default definition with an id and an effect or setup function, because both entry points exported only the OpenCode 1.x shape. The server and TUI entries now also export an OpenCode 2 setup built with Plugin.define from @opencode/plugin, next to the OpenCode 1.x server and tui entries, which keep working as before. Each OpenCode 2 start shows a notice that points to OmO Native, with the install command and guide link. (#8485, #10439)
The frontend skill keeps coloured edge stripes off rounded cards, and a linter catches the ones that slip through. A card with a coloured stripe along one edge, its rounded corners bending the stripe, is one of the most recognizable marks of generated UI, and the skill only banned it when the stripe marked a selected or focused item. It now rules the stripe out before drafting, whether it decorates the card or marks state, and offers what to use instead: a tonal surface, a heading in the accent colour, a glyph, or spacing. The new check-accent-stripes.ts script finds the pattern in CSS, Tailwind classes, inline styles, and styled-components, and the skill's checklist runs it before visual QA. Focus rings, form validation, neutral dividers, and tables are left alone. (#10437)
A store extension's orderBy can only name columns its statement returns, and its text never reaches the SQL. orderBy used to be pasted into the gateway's ordered read as given, so a LIMIT, an OFFSET or a column the statement d...