OmO
A second DAG run in the same session waits for a resident slot instead of failing at start. Every run, team and task spawn of a session shares one resident-child cap (task.residency_max_children, 16 on a 14-core host). When one run's children held every slot, a second run failed all of its leaves within seconds with residency_denied: resident child cap reached and no task can free a slot, its aggregators were skipped, and the run then sat running forever because nothing was attached to drive it to a terminal state (#8396, #8398). The scheduler had judged the whole session by its own bookkeeping, which is empty for a run that arrives second. The task manager now exposes a session-scoped wake that fires when any resident child reaches a terminal status, is evicted or suspended, or drains its last pending send; a denied node stays scheduled, its first parking is journaled once as residency_queued with how many residents hold the cap and how many belong to other owners, and the scheduler re-probes on every wake. Only a denial that names no resident still fails a node. A run whose every leaf fails at admission now settles failed with its dependents skipped, so retry works on it. The mass-ulw capacity model documents that the queue holds across runs.
Children with a narrower tool policy can now receive parent JavaScript tools, scoped to their own permissions. A child spawned with tools: { write: false }, an excludeTools denial or any explicit allow/deny used to be refused a parent tool(fn) outright with tools_unavailable, because the closure's nested tool.<name>() calls ran with the parent's permissions. When the engine advertises per-invocation scoping (kernelTools.capabilities.invokeScope, senpi 2026.9.16-3 and later), OmO grants the narrowed child and sends its resolved effective tool policy as the scope of every nested call made on its behalf: the exact allow list the runner installs for that child plus its literal deny list (#8226, #8394). A nested call outside that scope is refused inside the worker and lands on the child's own tool-result channel as a typed kernel_tool_host_denied envelope, so the child can recover and the parent's cell never fails for it. The kernel_tools status record says whether the grant was scoped. Curated read-only agents, team members, process children and non-JavaScript parents are unchanged.
ulw-loop no longer rebuilds goals.json below what its ledger records. A run created under the removed omo_agent_toolkit tool path could publish a revision with one goal, keep adding goals and evidence straight into goals.json and ledger.jsonl, and then lose every later goal, its evidence and its audit entries the first time the agent-toolkit-sdk rebuilt the projection from that older snapshot; record-evidence and checkpoint on those goals failed with ULW_LOOP_GOAL_NOT_FOUND (#8328, #8388). Reconciliation now lets a goals.json that names goals the newest snapshot lacks win, stamps it so the next publish folds the whole plan into revision N+1, and attributes ledger lines appended after a published revision to that revision. Every write of goals.json is checked against the reconciled ledger: a goal the plan lacks is a typed ULW_LOOP_PROJECTION_TRUNCATED refusal that names the missing ids, never a silent truncation.
One kibitzer_summary telemetry event per session measures the memory sidecar. How many nudges it delivered and on which wake the first one landed, what the wakes cost in tokens and wall time, how often they interrupt (median and p90 gap between nudges), and how many wakes were buffered by the cooldown or had nothing new to say (#8389, #8390). The event carries counts, durations and a masked model id only; nudge paths and hint text never reach telemetry. An idle session emits nothing.
LSP diagnostics no longer miss a publish that lands before the wait registers, and contended lock waits stop hammering the disk. The diagnostics client could resolve an empty list when the server's answer arrived in the gap before its freshness wait was armed; the wait now orders on the schedule of that publish. acquireLock re-attempted a full exclusive publish (create, write, fsync, hard-link, unlink) on every retry tick, so a waiter aimed roughly 200 fsynced create and unlink cycles per second at the volume the lock holder was writing to; it now reads the lock file first and publishes only when the lock is free (#8323, #8391). The Windows console probe asks kernel32 through bun:ffi instead of compiling a C# shim on every call, and the two spawn-heavy scripts that starved under Windows --parallel run in the shared serial quarantine with their measurements recorded. No test budget was raised and no assertion weakened.
- fbcc57e Merge pull request #8399 from code-yeongyu/release/v5.0.0-beta.68-source-state
- 68e0b38 Merge pull request #8398 from code-yeongyu/fix/8396-dag-cross-run-residency
- 51753a8 docs(changelog): draft the 5.0.0-beta.68 notes under Unreleased
- ee17c22 Merge pull request #8391 from code-yeongyu/fix/8323-windows-shard-starvation
- 08e62c1 Merge remote-tracking branch 'origin/dev' into fix/8323-windows-shard-starvation
- 776c466 Merge pull request #8394 from code-yeongyu/feat/8226-invoke-scope-consumer
- 857f5ca Merge remote-tracking branch 'origin/dev' into fix/8323-windows-shard-starvation
- 9a1d589 Merge remote-tracking branch 'origin/dev' into feat/8226-invoke-scope-consumer
- d448b7a Merge pull request #8393 from code-yeongyu/test/kibitzer-summary-registration-order
- afeed3f Merge remote-tracking branch 'origin/dev' into fix/8323-windows-shard-starvation
- 5c4f07f Merge pull request #8390 from code-yeongyu/feat/kibitzer-telemetry-summary
- f844b7f Merge remote-tracking branch 'origin/dev' into fix/8323-windows-shard-starvation
- e39f225 docs(evidence): record RED/GREEN, QA scope and bundle control for kibitzer_summary
- bee849b Merge pull request #8388 from code-yeongyu/fix/8328-ulw-loop-projection
- ded3c1a fix(lsp-core): stop losing a publish that lands before the diagnostics wait registers
- 199faba fix(ci): make the Windows shards deterministic under their existing budgets
- 680ef41 fix(ulw-loop): fold an ahead-of-snapshot goals.json into the next publish and refuse truncated projections (fixes #8328)
npm i -g omo-ai@beta