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
Add trusted ClawSweeper-label and maintainer-comment dispatch for Mantis Telegram proof. Short-circuit non-visible PRs before desktop setup while preserving exact-head, fork, credential, and comment-ownership boundaries.
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>
The "includes weekday and relative time" test computed the expected
weekday with the ambient host locale (`toLocaleDateString(undefined, ...)`)
while `formatNextRun` formats the weekday through `i18n.getLocale()`
(default "en"). On hosts whose default locale is not English (e.g.
`LANG=zh_CN.UTF-8` -> "周一"), the two diverge and the slice assertion
fails: `expected 'Mon,' to be '周一, '`.
Mirror `i18n.getLocale()` in the test so the expected weekday always
matches the locale the presenter uses. No production behavior change.
Verified: passes under `LANG=zh_CN.UTF-8` and `LANG=C` via
`pnpm test:unit:fast -- test/ui.presenter-next-run.test.ts`.
AI-assisted.
* test(unit-fast): isolate computer-tool.test-helpers consumers
The unit-fast shard classifier recognizes "stateful" test helpers
(those whose source trips a disqualifying pattern such as `vi.mock(`
or top-level dynamic `import`) via `statefulTestHelperImportPattern`,
so that tests importing them are routed to the isolated pool instead
of the shared `isolate:false` pool.
`computer-tool.test-helpers` was missing from that pattern, even though
the helper sets up `vi.mock("./gateway.js")`, `vi.mock("./nodes-utils.js")`
and uses top-level `await import(...)` — i.e. it is stateful. Its
consumers (`computer-tool.v2/schema/context.test.ts`) therefore
classified with empty `reasons`, fell into the `isolate:false` pool,
and relied on `vi.mock` against a shared module registry. When another
test file loaded the real `./gateway.js` / `./nodes-utils.js` in the
same worker first, the mock was bypassed and `computer-tool.v2.test.ts`
threw `GatewayCredentialsRequiredError: gateway node.list requires
credentials` for all 8 of its cases — while passing in isolation.
Add `computer-tool\.test-helpers` to the pattern (mirroring the existing
`message-action-runner\.test-helpers` entry) so consumers are routed to
the isolated pool where the mock is honored.
Verified on `main` (`83d279a`), Node 24.15.0:
- Before: `pnpm test:unit:fast` -> 8 failures in
`src/agents/tools/computer-tool.v2.test.ts` (`GatewayCredentialsRequiredError`);
the file passes alone (8/8).
- After: the three consumers classify `inIsolated=true`; `pnpm test:unit:fast`
no longer runs them in the shared pool; the suite's only remaining
failures are unrelated (`test/ui.presenter-next-run.test.ts` locale,
`test/scripts/resolve-openclaw-ref.test.ts` git version) and the
computer-tool suite passes (16/16) under `vitest --isolate`.
AI-assisted.
* test(unit-fast): cover computer-tool helper isolation
Punchcard-Session: ember-willow-valley-9r
---------
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
* 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.
`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.
Hybrid runs attempt 1 on Blacksmith but packs bins with the GitHub-calibrated
`COMPACT_GITHUB_GROUP_SECONDS_HINTS`. Measured across four healthy main runs
(32316204633, 32317242374, 32318250756, 32320063231), normalized per run by
that run's own VM speed, those hints land at 0.64x on Blacksmith across 100
groups -- so nearly everything is over-predicted and only five groups overshoot:
core-runtime-infra-process x2.03 34.5s vs 17
agentic-cli-process x1.64 109.8s vs 67
agentic-agents-core-models x1.45 81.3s vs 56
core-runtime-cron-service x1.35 107.8s vs 80
agentic-commands-doctor x1.30 82.9s vs 64
Those five are exactly the ones that matter: an under-predicted group leaves
budget for partners, so the packer piles work onto the bins that already set the
wall. Replaying the plan against the measured per-shard medians, the tallest bin
drops from 164s to 141s of test time and the runner-up from 151s to 140s, for one
extra job (47 -> 48 on push). The plateau is flat and queue time is ~2s, so the
extra job is free and the 23s comes straight off the critical path.
Guard counts move with the plan; they exist to make repacking deliberate, and the
150s non-dist ceiling and 140s max are unchanged.
* fix(package): bound worker artifact parsing
Keep canonical self-contained worker bundles above the generic dist-file cap while enforcing an 80 MiB limit before installed-package verification reads or parses them.
* fix(package): bound every verifier read
Route the context-engine and dependency scans through one root-dist pre-read policy, exclude plugin-owned extension assets from the root marker contract, and cover the public verifier flow.
* fix(cron): honor failure alert thresholds
Per-run Gateway announcements bypassed threshold, cooldown, and opt-out policy. Make the scheduler the sole owner of failure notification decisions.
* fix(cron): preserve safe failure details
Keep trusted failure detail proof on the scheduler-authorized transport and remove the obsolete Gateway event-context handoff after the ownership consolidation.
* test(cron): assert alternate failure route isolation
* Move raw transcript from system to user prompt to protect provenance.
* Type fix.
* fix(voice-call): harden transcript context handling
* fix(voice-call): initialize inbound Twilio control state
* test(voice-call): align runtime coordinator fixture
---------
Co-authored-by: joshavant <830519+joshavant@users.noreply.github.com>
* feat(ui): unify focused presentation routes
/focus/<target> replaces unshipped standalone query links across dashboard, terminal, desktop, and native apps.
Gateway-served index assets are anchored so nested documents resolve their bundles from the Control UI base path.
* test(gateway): narrow emitted asset URLs
Fixes check:test-types TS18048/TS2322 by dropping unmatched optional captures before comparing emitted asset URLs.
* test(docs): follow centralized cloud secret guidance
Fixes the stale current-main docs test after #126132 centralized GCP and Hetzner setup in docker-vm-runtime.
* test(ui): retry missing locator reads
The 500ms locator text read can time out while the menu label is still rendering, causing expect.poll to reject instead of using its owning 10s retry window. Treat only Playwright TimeoutError as a missing value so the outer poll retries while page-closure and arbitrary failures still surface.
* test(android): capture TLS probe coroutine
The TLS probe test inferred its coroutine from mutable scope children, racing unrelated child startup and teardown in CI. Capture the exact Job from inside the probe coroutine and join that owner before asserting the stale-attempt guard.
* fix(gateway): preserve plugin focus routes
Keep approval handling ahead of plugin dispatch, but treat focus documents as an unclaimed Control UI fallback after plugin authentication and routing. Exact and prefix plugin routes therefore retain ownership, while unclaimed reads serve the focus document and other methods return 404.
* fix(ui): migrate released terminal links
Preserve stable v2026.7.1 terminal query compatibility by rewriting the root/base ?view=terminal URL once to the canonical /focus/terminal path with history.replace. Keep URL parsing path-only, and leave the removed desktop and dashboard query forms as a hard cut.
* test(codex): assign run-attempt tools shard
Cached filtered configs caused duplicate ownership, and the test lacked a canonical full-suite owner.
* test(ui): keep cloud recovery proof state-owned
The recovery test should assert owner state and reload identity, while dedicated tests own transient alert visibility.
* test(qa): wait for outbound bus state
* fix(qa): reserve gateway ports through staging
* refactor(qa): keep socket creation in gateway owner
* fix(update): validate target config before handoff
Run the existing dev candidate preflight from both managed update entry points while the serving Gateway remains alive. Reject target-incompatible config before starting a handoff or scheduling restart. Closes#126269
* fix(protocol): restore gateway barrel line budget
Route SessionsPatchResult through the existing type-only schema barrel so the public export stays intact without exceeding the core max-lines gate.
* fix(ci): restore required PR gates
Keep schema-types as the registry-free wrapper, drop a redundant project schema re-export to restore the line budget, claim run-attempt-tools in one canonical shard, and align campaign tests with the new preflight boundary.
* fix: capture GitHub identity from authenticated sign-in
Automatically persist verified GitHub identities from Cloudflare Access and Tailscale Serve while keeping public Git co-author credit as a separate opt-in.
* test: stabilize cleanup and activity capture
* fix(security): bind GitHub profiles by account id
* test: scope activity capture to route
* fix(security): gate profile requests on identity sync
* fix(security): close pending profile authorization gaps
* test(ui): stabilize terminal continuation menu
* test: stabilize startup recovery timing
* test: keep one Codex attempt tools owner
* fix(plugins): allow profile-independent gateway reads
Three PRs fixed the same orphaned test within minutes of each other -- #126222,
#126225 and #126190 -- so the full-suite ownership audit flipped from "missing" to
"duplicated" and main went red at 554dfbe0a2.
Keeps the claim from #126225, whose entire purpose was routing this test, and drops
the two incidental ones added while landing unrelated UI work. The audit passes 18/18
and the test still runs, once, in the attempt-light shard.
Root cause is the shard layout: the support shard globs app-server/**/*.test.ts but
excludes the whole run-attempt* pattern while the attempt shards enumerate by
filename, so every new run-attempt-* file is unowned until someone hand-adds it, and
concurrent fixers then collide.
Pinned sessions inherited the nav zone's muted colour on the session *title*, so a
pinned row's preview line outshone its own name and the same session read dimmer
pinned than unpinned. A title is content in every zone; only glyphs, meta and the
hover fill follow the zone. The subtitle drops to plain --muted, already proven AA
against every surface by theme-contrast.test.ts.
Rows with no preview text reserved a fixed 18px second line anyway, leaving a dead
band or a lone spinner hanging below-right of the title. They now collapse to one
line via a --single-line class plus a CSS variant, so the endcap rides beside the
title. Rows also gained a little vertical air and reclaimed the right-hand gutter
inside the row, leaving the deliberate scrollbar clearance from #124879 intact.
Adds a localStorage-backed "Show message preview" toggle to the session sort menu
(default on). Operator-actionable state is exempt: attention, the queued
concurrency-slot explanation, and critical observer headlines (stuck /
waiting-on-user) always show, because hiding them behind a display preference is
the silent-failure class.
Also registers extensions/codex/src/app-server/run-attempt-tools.test.ts, which
arrived in #126189 with no shard claim and left main red.