* feat(ui): add cpu/memory graphs to system busyness overlay
* refactor(ui): redesign busyness overlay vitals as sparkline stat tiles
Merge the duplicated sparkline row and numeric tile grid into three vital
tiles (CPU, memory, event-loop delay) with gradient area charts, a live
pulse dot, pointer scrubbing with value+age readout, and a danger tint
driven by the gateway's own event-loop degradation reasons. Memory
auto-ranges its baseline so RSS trends stay visible.
* feat(ui): add Person grouping mode for sessions sidebar and sessions page
Sessions can now be grouped by their durable owner identity: the sidebar
Group-by menu gains a capability-gated Person mode (self first, humans by
label, agent identities after; ownerless rows keep their smart zones), and
the sessions page gains the matching person mode. Person section headers
render the owner avatar and profile label; the mock dev server now
advertises the multi-identity policy and carries explicit row owners the
way the gateway projects createdActor fallbacks.
* feat(ui): gate sessions-page Person grouping on the identity capability
Mirrors the sidebar: the Person option hides without
hasMultipleSessionSharingIdentities and a stored Person preference
renders as None until the capability returns.
* fix(scripts): keep Windows lint runs from failing before any file is checked
`pnpm lint:extensions` aborts on Windows whenever the plugin SDK boundary
cache is cold: the boundary prep spawns `node_modules/.bin/tsgo` directly,
and Windows cannot execute the extensionless pnpm shim, so the run dies with
ENOENT before oxlint checks a single file. The stylelint runner reached by
`check-changed` fails the same way for the same reason.
Both now build their child process with `createManagedCommandInvocation`,
the launcher every other repo tool runner already uses, which routes the shim
through cmd.exe on Windows and returns the command unchanged everywhere else.
Off Windows the spawned command, arguments, and options are byte-identical to
before, so only the broken platform changes behavior.
* fix(scripts): stop the lint pipeline from spawning a tool shim directly
`pnpm lint` reaches stylelint through the same raw shim spawn that broke the
boundary prep, so the pipeline dies on Windows after oxlint succeeds. Route it
through the managed launcher like every other tool runner.
The remaining hazard is structural: the resolver hands out a path that only
some callers know to normalize, and the three sites that forgot were spread
across two spawn shapes. Add a static guard so a shim can only flow into a
launcher that understands the platform, and so the next occurrence fails on
Linux CI instead of on a contributor's Windows machine.
* test(scripts): trim Windows shim regression coverage
Punchcard-Session: cobalt-orchard-willow-2q
---------
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
Make long, free-form Telegram proof runs truthful and resilient. Keep the trusted mock harness current across historical SUTs, preserve intentional silence and blocked outcomes, remove fixed attempt/lifetime caps, and export cropped motion proof without the prior memory spike.
Co-authored-by: Ayaan Zaidi <hi@obviy.us>
Remove the premature visibility classifier and let one proof agent configure and exercise the disposable Telegram gateway. Align mock response timing with the 15-minute lane budget while preserving credential isolation through the alias-token proxy.
Preserve honest blocked proof outcomes and publish visible stop-reports without marking them passed. Serialize burst runs through the authoritative Telegram-user lease while reserving time for proof and cleanup.
Host zlib versions compress identical startup assets into different bytes, causing false Linux budget failures. Emit canonical shipped pako gzip sidecars, restore the 512 B ratchet tolerance, and lower the startup baseline from 348351 B to 344531 B.
Give maintainers immediate visibility when Mantis is requested. Bare mentions now react, link the active run, and keep one run-owned status comment through proof, short-circuit, or failure.
Co-authored-by: Ayaan Zaidi <hi@obviy.us>
* fix(gateway): admit recovering workers during startup
* fix(gateway): admit recovering nodes during startup
* fix(crabbox): bind worker desktop to XFCE session
* fix(workers): reuse Git base during workspace transfer
large clean/stale worktrees were downloading every tracked file after the verified base pack, crossing transfer authority; selectively checkout desired base-index paths, preserving deletions and symlink confinement.
* fix(workers): clone reachable stale workspace commits
tip-only origin detection forced published ancestor commits through heavyweight Gateway transfer; the existing exact checkout and manifest verification safely own reachability/fallback.
* perf(workers): use blobless origin clones
* fix(workers): bundle undici in worker deploy artifact
Move Mantis Telegram Desktop proof from the remote AWS/Crabbox lane to a recorder-driven local Docker desktop. Keep proof scenarios agent-authored, cache trusted build outputs, and publish exact visible Telegram evidence without writing the QA bot token to artifacts.
Co-authored-by: Ayaan Zaidi <hi@obviy.us>
* refactor(agents): reduce tool failure warnings to two rules
* test(agents): remove obsolete tool recovery receipt proof
* refactor(agents): drop unused meta param from buildToolMutationState
* test(agents): remove stale tool warning assertions
* test: export runtime source snapshot from closed runtime-snapshot mocks
Heal the main breakage introduced by 9441e3fe6e / #126531, which added a runtime source-snapshot read to provider model route resolution. Closed Vitest factories now return null for that source snapshot, preserving their pre-projection behavior.
* test(gateway): make compaction read-error faults order-immune
Generation-2 CI failure in run 32342180898, job 96343444772 showed that the mock factory initialized while shared gateway-server importers remained bound to the real transcript reader.
The dedicated isolated project fixes normal shards. Complete its ownership by adding it to the root project matrix and excluding the test from the non-isolated OPENCLAW_GATEWAY_PROJECT_SHARDS=0 fallback.
* fix(auth): keep a retired auth JSON from stranding a migrated store
Runtime failed closed with AUTH_PROFILE_MIGRATION_REQUIRED whenever a retired
credential file was present, even when the canonical SQLite store already held
the agent's profiles. One leftover auth.json therefore made a fully migrated
install unusable, and the gateway lifecycle preflight refused start/restart on
top of it, so every channel and provider stayed offline until Doctor ran.
A legacy file is now only fatal when the canonical store cannot serve
credentials. Doctor's importer never overwrites a usable stored credential, so
a file sitting beside a populated store is unarchived bytes, not pending
migration: runtime logs a one-time warning and keeps serving. An empty store
with a credential file still fails closed and never falls through to
environment auth. Startup degrades that owner to configured-unavailable
instead of refusing to boot, which lets the lifecycle preflight go away.
* refactor(secrets): retire the auth-profiles.json vocabulary
Auth profiles moved to SQLite, but operator-facing surfaces still named the
retired JSON file. The duplicate-agentDir error told operators to copy
auth-profiles.json to share credentials, which does nothing and lands the
second agent in a migration-required state; `openclaw migrate plan codex`
reported a target file that is never created; and the secrets picker labelled
candidates with a filename that no longer exists.
Renames the SecretTargetConfigFile discriminator to "auth-profile-store" and
corrects the operator-facing text, the migrate plan target, and the docs that
described the file as a live target. Genuine legacy-filename uses in doctor,
the security fixer, and migration fixtures are unchanged.
Also deletes resolveSecretPlanTargetByPath and ResolvedSecretPlanTarget from
the plugin SDK. They have no callers in core, plugins, or tests, and the
symbols are absent from the latest stable tag, so they carry no compatibility
obligation and are removed rather than deprecated. Their inline parameter type
was the only thing putting the retired filename on the public SDK surface.
* improve(wizard): warn about device-code phishing
The device-code prompt only warned against sharing the code, and only when an
expiry was known. Device-code phishing works the other way around: the attacker
starts the login and gets the victim to enter the attacker's code. Codes
delivered over a chat channel are the risky case and carry no expiry hint, so
the warning is now unconditional and covers received codes, matching the Codex
CLI prompt.
Also documents the Codex auth handoff: a subscription profile is installed as
in-memory external auth rather than persisted, and token refresh is inverted
so the refresh token stays in OpenClaw's store.
* fix(test): make transcript read-failure injection order-independent
server.sessions.compaction-read-errors.test.ts injected its failures with
mockRejectedValueOnce, which fails the NEXT call to loadTranscriptEvents
globally. Under --isolate=false a shard shares one worker, so any sibling
transcript read could consume the one-shot rejection before the compaction RPC
issued its own; compaction then ran against the real reader and returned ok,
failing three assertions. This shard was already red on main; a prior repair
fixed the mock's initialization order but left the call-order dependency.
Key the injection on the seeded sessionId instead, so unrelated readers cannot
consume it and the re-read case counts only its own session's reads.
Also updates two expectations invalidated by this branch: the duplicate-agentDir
remediation text, and the plugin SDK export ratchet, shrunk by the two retired
secret-plan exports.
`server.sessions.compaction-read-errors` mocks
`config/sessions/session-accessor.sqlite-read.js`, but production reaches
`loadTranscriptEvents` through re-exports: `server-methods/sessions-compact.ts`
imports it from the `session-accessor.js` barrel and
`preflightSessionTranscriptForManualCompact` imports it from the leaf. The
`gateway-server` project is `isolate: false`, so when a neighbour has already
evaluated those importers they stay bound to the real implementation and the
mock never fires -- the injected read error simply does not happen and all three
tests fail with `expected true to be false`, reading like a product regression.
Trigger: 33744584f3 added `server.chat-metadata-boundary.test.ts`, which boots
a full non-minimal Gateway in `beforeAll` and lands immediately before this file
in the shard. Main has gone red on it repeatedly since (32338154086, 32339521003,
32339928383, 32341300955, 32341946296); e294c154a6 fixed only the sibling
symptom where the factory had not run yet.
Route the file to a new `gateway-server-isolated` project instead, mirroring
`unit-fast-isolated` -- whose comment describes this exact hazard. A fresh graph
per file makes both symptoms structurally impossible rather than order-dependent.
The list is explicit so the reason travels with the file.
Not reproducible on macOS: the exact 24-file stripe in CI's own order, and the
triggering pair three times, are green locally every time.