Commit graph

79736 commits

Author SHA1 Message Date
Peter Steinberger
66db70133b
perf(test): avoid Canvas Git timeout wait (#124547)
Some checks are pending
Native App Locale Refresh / Refresh native hi (push) Blocked by required conditions
Native App Locale Refresh / Refresh native id (push) Blocked by required conditions
Native App Locale Refresh / Refresh native it (push) Blocked by required conditions
Native App Locale Refresh / Refresh native ja-JP (push) Blocked by required conditions
Native App Locale Refresh / Refresh native ko (push) Blocked by required conditions
Native App Locale Refresh / Refresh native nl (push) Blocked by required conditions
Native App Locale Refresh / Refresh native pl (push) Blocked by required conditions
Native App Locale Refresh / Refresh native pt-BR (push) Blocked by required conditions
Native App Locale Refresh / Refresh native ru (push) Blocked by required conditions
Native App Locale Refresh / Refresh native sv (push) Blocked by required conditions
Native App Locale Refresh / Refresh native th (push) Blocked by required conditions
Native App Locale Refresh / Refresh native tr (push) Blocked by required conditions
Native App Locale Refresh / Refresh native uk (push) Blocked by required conditions
Native App Locale Refresh / Refresh native vi (push) Blocked by required conditions
Native App Locale Refresh / Refresh native zh-CN (push) Blocked by required conditions
Native App Locale Refresh / Refresh native zh-TW (push) Blocked by required conditions
Native App Locale Refresh / Commit native locale refresh (push) Blocked by required conditions
OpenClaw Stable Main Closeout / Resolve stable release closeout inputs (push) Waiting to run
OpenClaw Stable Main Closeout / Verify stable main closeout (push) Blocked by required conditions
Plugin Init Scaffold Validation / Validate provider scaffold (push) Waiting to run
Plugin NPM Release / preview_plugins_npm (push) Waiting to run
Plugin NPM Release / Validate release publish approval (push) Blocked by required conditions
Plugin NPM Release / preview_plugin_pack (push) Blocked by required conditions
Plugin NPM Release / Preflight plugin npm package () (push) Blocked by required conditions
Plugin NPM Release / Trusted publisher OIDC exchange (push) Blocked by required conditions
Plugin NPM Release / publish_plugins_npm (push) Blocked by required conditions
Plugin NPM Release / verify_plugins_npm (push) Blocked by required conditions
Workflow Sanity / no-tabs (push) Waiting to run
Workflow Sanity / actionlint (push) Waiting to run
Workflow Sanity / generated-doc-baselines (push) Waiting to run
2026-08-16 05:06:53 -07:00
Peter Steinberger
6e7b1e2215
fix(gateway): honor pairing exemptions on reconnect (#124545) 2026-08-16 05:05:11 -07:00
Peter Steinberger
23a034d584
fix(cli): scope unknown-subcommand help to its command tree (#124544) 2026-08-16 05:03:00 -07:00
Peter Steinberger
bba57301d9 perf(ci): fold built-runtime verifiers into the artifact-check wave
build-artifacts is the wall's pole in 4 of the last 5 main runs (171-186s,
~15-20s ahead of the next lane), so its serial steps are the wall. The
Doctor plugin-index proof, singleton smoke, and startup-memory check ran
as their own 13s step even though they are independent dist readers that
the 47s artifact-check wave could absorb.

They now run inside that wave: on Blacksmith all seven start together, so
the verifiers cost the wave's max instead of 13s of serial time; hosted
runners still serialize the three through run_verifier so the RSS ceiling
measures an unloaded process. The step drops its selection gate because
the verifiers always run -- each artifact check already self-gates on its
own RUN_* flag, so a run with no checks selected still verifies.

Proof: extracted the step body and ran it with stubbed pnpm/node. Both
modes behave (Blacksmith 7 checks started, hosted-with-nothing-selected
still runs the 3 verifiers), and a failing verifier exits 1 with its
::error annotation in both -- the wave cannot swallow it.
2026-08-16 04:52:56 -07:00
Peter Steinberger
dbad5e385d
refactor(workers): separate runner consent from capacity (#124356)
* refactor(workers): separate runner inventory state

* docs(runners): track inventory cleanup

* test(workers): use bundle-only launch wire

* test(workers): update optional inventory fixture

* test(workers): validate prewarm inventory capability

* fix(workers): version runner inventory cutover
2026-08-16 04:46:38 -07:00
Peter Steinberger
ee4bd4aa47 fix(scripts): give the artifact mtime repair a millisecond of headroom
checks-node-core-tooling-2 failed on main (run 31943910358) with
'expected 1786879225197 to be >= 1786879225197.2246': the repaired output
mtime landed a fraction of a millisecond below the input it had to clear.

isArtifactSetFresh repairs output mtimes to exactly ceil(newestInput), so
it leaves zero headroom for sub-millisecond write rounding or lagging
metadata on CI filesystems. When the repair lands at or below its input
the mtime fast path never engages, and every later invocation in that
checkout falls back to re-hashing every input byte -- the expensive path
this repair exists to avoid, gating the d.ts emit that is the slowest
build-all phase (25.9s of a 61s build).

Neither macOS APFS nor an idle Linux ext4 Testbox reproduces the
shortfall in 300 runs, so the repair now clears the newest input by a
whole millisecond instead of matching it. The assertion pins that
headroom, making the test deterministic where it was previously
load-dependent (fails 615 vs 616 without the fix).
2026-08-16 04:40:23 -07:00
Peter Steinberger
96cacfdf74
fix(gateway): batch worker placement session evidence (#124372)
* perf(gateway): batch worker placement session evidence

* test(gateway): tolerate elapsed workspace timeout

* fix(gateway): preserve unknown placement evidence

* fix(sessions): validate batched placement evidence

* fix(gateway): preserve incognito placement evidence

* fix(sessions): bound configured target discovery

* fix(gateway): canonicalize batched placement evidence
2026-08-16 04:28:06 -07:00
Peter Steinberger
b07c6b2b8b
fix(computer-use): macOS live-proof rig deadlocks on operator device approval (#124536)
* fix(computer-use): unblock the macOS live-rig proof flow

The rig ran its operator CLI and its proof runner from one state dir, so both
shared one device identity. A paired operator device is pinned to the scopes of
its first connect, and `nodes list` connects first for `node.pair.list`
(operator.pairing); the proof runner then needs operator.write, which is a scope
upgrade the gateway never approves silently and which no rig client can approve
for itself. The proof runner is a GATEWAY_CLIENT/BACKEND client, so on a
loopback auth-none gateway it is admitted unpaired with the scopes it asks for:
giving the CLI its own `cli-state` identity is enough, and `agent-state` now
never accumulates a pairing row.

`nodes list` also read `node.list` through the plain CLI client while
`nodes status`/`describe` used the diagnostics ladder. On any gateway where the
CLI must pair, the unfiltered list silently dropped connected/commands/
computerUse and `--connected` failed outright, so the documented rig gate could
not confirm the node. Both call sites now use `callNodeDiagnosticsGatewayCli`.

Docs drop the `devices approve <requestId>` instruction, which was circular:
that invocation is its own new device identity.

* test(cli): share the runtime-log formatter across nodes CLI e2e files

The extracted diagnostics-auth file stringified captured log arguments directly, which the type-aware core lint stripe rejects (no-base-to-string). Move the existing formatter into the shared node test helpers instead of duplicating it.
2026-08-16 04:25:03 -07:00
Peter Steinberger
d86593fa28
fix(gateway): prevent sustained-turn readiness stalls (#124528)
* perf(gateway): reuse prepared plugin generations

* fix(agents): break prepared runtime import cycle

* chore: keep release notes in PR body

* test(agents): preserve plugin snapshot mock exports

* test(agents): consolidate plugin generation coverage
2026-08-16 04:20:46 -07:00
Peter Steinberger
0c546979b2
fix(release): exclude RoboClaw from contributor credit (#124526) 2026-08-16 03:19:26 -07:00
Peter Steinberger
15a01bcc5e
fix(sessions): reject invalid explicit store paths (#124515)
* fix(sessions): validate operator-supplied store paths

* fix(sessions): preserve legacy store selectors

* style(sessions): avoid unchecked store assertions

* fix(sessions): keep store errors concise

* chore(sessions): document SQLite schema probe
2026-08-16 03:06:43 -07:00
Peter Steinberger
3f4dd7119f
fix(cron): keep error class names out of run history (#124511)
* fix(cron): keep error class names out of run history

* fix(cron): preserve lifecycle abort reason

* fix(cron): preserve coded abort reasons

* docs: record cron abort follow-up
2026-08-16 03:03:23 -07:00
Peter Steinberger
d5f41f734b
fix(ci): trust QA tooling for frozen targets (#124509)
* fix(ci): trust QA tooling for frozen targets

* fix(ci): validate frozen QA tooling context

* fix(ci): verify frozen context without checkout

* fix(ci): pin QA tooling to workflow revision
2026-08-16 02:41:24 -07:00
Peter Steinberger
77902b185d
fix(tasks): validate filter flags before querying (#124520) 2026-08-16 02:13:57 -07:00
Peter Steinberger
46f5951d53
fix(audit): reject filter combinations that cannot match (#124513) 2026-08-16 02:09:23 -07:00
Peter Steinberger
e12079fb13
fix(gateway): keep readiness aligned with chat dispatch (#124514) 2026-08-16 01:59:08 -07:00
Peter Steinberger
b9901605e8
fix(backup): report archive problems instead of raw errno text (#124510) 2026-08-16 01:46:23 -07:00
Peter Steinberger
32ddbb3be2
fix(ui): chat send failures were invisible when the session pane was hidden (#124473)
* fix(ui): always surface terminal chat send failures

Terminal chat send failures were recorded only on the queue item when the
owning pane was not visible (reconnect, alias drift, split-pane routing),
so the operator saw nothing at all — an action ending in silence.

Root cause: every error surface in the send/drain path was gated on
visibleSessionMatches(...), and the FIFO outbox drain treated every
chat.history reconcile rejection as a silent retryable "blocked", so a
non-retryable rejection (e.g. auth loss) wedged the head — and everything
behind it — permanently with no visible outcome.

Fix, at the owner:
- New surfaceChatDeliveryFailure() in steer-lifecycle.ts (the shared
  error-text owner): visible pane keeps the inline chat error; otherwise
  the failure routes through the existing global toast host, naming the
  session. All terminal failure sites in chat-send-delivery,
  chat-outbox-drain, chat-send-queue-state, and steer-lifecycle now use it.
- reconcileStoredChatOutboxHead: a non-retryable GatewayRequestError on the
  head now terminally fails a never-attempted head (unblocking the lane)
  or parks an attempted head as unconfirmed — both with a visible outcome —
  instead of blocking the lane forever.
- Composer disabled-reason: the reason now also renders while a draft hides
  the placeholder, and the cloud-startup-pending gate gets a reason instead
  of a silently disabled composer.

Regression tests: hidden-pane terminal failure surfaces via toast; wedged
head fails visibly and the lane drains the next message; attempted head
parks unconfirmed; disabled reason visible with draft text present.

* fix(ci): raise startup JS baseline for global failure surfacing and pin workspace-sync test clock

The chat send path now imports session-display naming for the global
failure toast, adding ~1 KiB gzip to startup JS (335452 B on CI's Linux
builder, still well under the 358400 B committed cap).

workspace-sync "never commands" asserted the exact dispatch timeoutMs
(777) but the impl derives it from a Date.now() deadline, so any elapsed
ms between admission and dispatch failed the exact-equality assertion on
a loaded runner. Pin the clock like the sibling timeout tests do.

* fix(ui): surface route-switched command failures and agent-scope global toast naming

ClawSweeper review findings on #124473:

- A queued local command failing after the operator navigated away hit
  failCommand(error) with expose=false; the dispatcher's stale-scope
  guard had already withheld the inline error, so a successful state
  write recorded the failure invisibly — the silent class this PR
  removes. Expose it globally when the scope is stale and the owning
  pane is hidden; a stale scope with the pane still visible keeps the
  failed queue chip (the new connection owns the inline surface).
- Global session rows are agent-scoped behind one shared "global" key,
  so the toast row lookup could borrow another agent's label. Match the
  row's agentId to the failed outbox's agent for global keys.

Both regression tests fail pre-fix (stash-verified).
2026-08-16 01:38:06 -07:00
Peter Steinberger
b097aaab20
fix: doctor --fix reports config changes that were never written when validation refuses the candidate (#124462)
* fix(doctor): never report unpersisted config fixes

doctor --fix printed "Doctor changes" panels while computing candidate
mutations, then crashed with a raw Error and persisted nothing when the
repaired candidate still failed write validation (e.g. an unknown root
key repaired alongside an unrepairable schema type error).

Root cause: the compute->print->validate->persist ordering was wrong.
Panels were printed at mutation time, but validation only ran inside the
atomic writer, after all panels were visible.

Fix at the owner boundaries:
- doctor-config-flow queues repair-mode "Doctor changes" panels in a
  sink instead of printing them; preview panels still print immediately.
  Committed side-effect repair notes (SQLite/filesystem) keep printing
  at repair time; candidate-config notes from the repair sequence are
  routed through the same deferred sink.
- io.write throws a typed CONFIG_VALIDATION_FAILED error (with the full
  issue list) via a new createConfigValidationFailedError owner in
  io.write-errors.
- runWriteConfigHealth prints queued panels only after the atomic write
  commits, and renders a validation refusal as a "Doctor warnings" panel
  stating no config changes were written plus the exact paths to fix by
  hand. The contribution loop stops after refusal (same invariant as the
  cron-ownership deferral) and doctor exits 1 without a raw Error leak.

Regression tests: pre-fix, the new validation-refusal e2e test fails on
the lying "Doctor changes" panel; contribution-level tests cover the
refusal note, held panels printing exactly once after commit, and no
retry of the identical candidate.

* fix(doctor): report partial persistence accurately after a later write refusal

Post-rebase CI and ClawSweeper follow-ups:
- repair-sequencing tests now assert the deferred configChangeNotes contract
  (candidate-only mutation notes moved out of changeNotes by the parent
  commit); committed side-effect notes stay in changeNotes.
- formatConfigValidationFailure is module-private; its guidance formatting is
  covered through createConfigValidationFailedError, fixing the knip
  unused-export gate.
- When the initial write pass committed and only the later post-repair write
  is refused, the warnings panel says earlier fixes were saved instead of
  claiming no config changes were written, and the outro says "some config
  fixes were not applied". New regression test covers commit-then-refusal.
2026-08-16 01:12:43 -07:00
Peter Steinberger
6f418b93c6
fix(outbound): persist mirror route only after successful delivery (#124459)
A failed message send (e.g. missing channel credentials on a fresh
install) durably rewrote the agent's folded main session route before
delivery was even attempted: prepareOutboundMirrorRoute called
ensureOutboundSessionEntry pre-send, stamping delivery.route/origin and
minting a conversations-registry row for the never-reached target. The
Control UI then showed the phantom channel identity and the composer
bound to a dead conversation.

Route resolution stays read-only in prepareOutboundMirrorRoute; the
durable write commits once per send at the first success proof:
identified platform evidence (onDeliveryResult) or plugin action
acceptance (onPluginSendAccepted), both before the in-delivery
transcript mirror so first-contact routes still create their session
row, with a post-return safety net for adapters whose results carry no
platform identity. The gateway send RPC sibling had the same pre-send
persistence and gets the same commit-on-evidence ordering.

Regression test proves a failed send leaves the seeded main-session
origin and conversation identity untouched while a successful send
still persists the mirror route; fails on pre-fix code.
2026-08-16 00:49:18 -07:00
Peter Steinberger
f19f62cb77
perf(node-host): prewarm worker bundles (#124427)
* perf(node-host): prewarm worker bundles

* test(gateway): gate worker finalization responsiveness

* fix(node-host): negotiate bundle prewarming

* fix(protocol): refresh worker prewarm models

* fix(node-host): preserve prewarm upgrade compatibility
2026-08-16 00:41:42 -07:00
Peter Steinberger
a2e27de593
fix(agents): sweep leaked files at prepared-absent paths during agent deletion (#124461)
Gateway agents.delete closed the agent database (unlinking -wal/-shm)
during preparation, then awaited config/cron/session-purge work that
reopened the database and recreated the sidecars. The sweep classified
those recreated files as foreign replacements ("cleanup path appeared
after deletion preparation"), preserved them, cascaded ancestor
protection over the whole agent directory, and finished the deletion
journal with exit 0 while ~157 files survived under agents/<id>/.

The deletion journal fence already blocks legitimate claims beneath
prepared paths, so a file that appears at a prepared-absent path can
only be leaked deleted-agent state: adopt its identity and sweep it
instead of preserving it. Prepared-present paths keep the existing
identity-mismatch protection for genuine operator replacements.

Regression tests: recreated WAL sidecars between preparation and
cleanup are trashed with the agent directory, and recovery sweeps a
file that appeared at a journaled prepared-absent path.
2026-08-16 00:27:23 -07:00
Peter Steinberger
063ce57caf
fix(gateway): cache prepared session targets (#124453) 2026-08-15 23:59:49 -07:00
Peter Steinberger
507e8b985e
fix(cron): finalize removed direct runs (#124457)
* fix(cron): finalize removed direct runs

* refactor(cron): clarify terminal outcome ownership

* docs(qa): record cron receipt audit

* chore(qa): remove product-branch audit report
2026-08-15 23:51:40 -07:00
Jason (Json)
bccbb8a0c7
fix(memory): make persistence promises receipt-backed (#120989)
* fix: require memory persistence receipts

* fix(memory): bind persistence failures to tool owners

* fix(memory): preserve Codex persistence ownership

* test(plugin-sdk): account for owner metadata export

* test(codex): split owner timeout regression

* fix(memory): cover durable deletes across runtimes

* test(codex): type dynamic mutation fixtures

* fix(agents): fail closed ambiguous side-effect owners

* fix(memory): fail zero-row delete receipts
2026-08-16 00:50:10 -06:00
Peter Steinberger
255ca8d96b
fix(ci): trust frozen plugin prerelease fixtures (#124446)
* fix(ci): trust frozen plugin prerelease fixtures

* fix(ci): apply scoped plugin test omissions
2026-08-15 23:47:25 -07:00
Nehorai Hadad
7d05f7c5b9
fix(auto-reply): suppress fallback notices in rooms (#107209)
Hide model fallback and recovery notices in group and channel conversations while preserving direct-chat notices, persisted state, and lifecycle events.

Co-authored-by: NehoraiHadad <nehorai.hadad.projects@gmail.com>
Co-authored-by: Ayaan Zaidi <hi@obviy.us>
2026-08-16 12:14:25 +05:30
Peter Steinberger
3554109801
fix(gateway): avoid stale session failure during model fallback (#124436)
* fix(gateway): defer provisional lifecycle errors

* fix(gateway): clear dormant observer retry timers

* fix(gateway): reuse observer timer cleanup on dispose

* refactor(agents): type lifecycle classifier input

* fix(agents): accept lifecycle payload records
2026-08-15 23:41:55 -07:00
Peter Steinberger
a4407f638a
fix(browser): reject ineffective Chrome MCP closes (#124449) 2026-08-15 23:31:27 -07:00
Aria
292ea7a338
fix(outbound): preserve angle-address emails in plain-text replies (#124249)
Preserve RFC 5322 angle-address emails without weakening namespaced tag stripping, and keep the iMessage security projection aligned.

Co-authored-by: Aria Ghasedi <drariaghasedi@gmail.com>
Co-authored-by: Ayaan Zaidi <hi@obviy.us>
2026-08-16 06:24:22 +00:00
Peter Steinberger
fa57fe5ae5
fix(ci): target sidebar reconnect roster response (#124430)
* test(ui): target selected reconnect roster request

* test(ui): decouple reconnect request scheduling

* test(ui): keep reconnect proof outcome-focused
2026-08-15 23:15:17 -07:00
Peter Steinberger
99bf0b1f3b
fix: preserve cloud workspace results across tunnel reconnects (#124406)
* fix: preserve workspace reconcile across tunnel reconnect

* fix: preserve reconcile before stateful tunnel dispatch

* fix: close reconnect pre-dispatch races

* style: satisfy reconnect gate lint

* test: align workspace action fixture
2026-08-15 23:11:11 -07:00
Peter Steinberger
03be260e5b
fix(lint): assertion SAFETY ratchet — exempt as-unknown, absorb merge drift (#124445)
* fix(lint): exempt as-unknown from SAFETY ratchet and rebaseline for merge drift

* chore(lint): refresh assertion baseline after rebase
2026-08-15 23:10:02 -07:00
chenshiyang
6a92cc3736
fix(agents): recover wrapped tool-search selectors (#124138)
Normalize one-level selector-less dispatcher wrappers before schema validation while preserving malformed outer-selector rejection.

Co-authored-by: chenshiyang.10 <chenshiyang.10@jd.com>
Co-authored-by: Ayaan Zaidi <hi@obviy.us>
2026-08-16 11:36:47 +05:30
Peter Steinberger
35011e49db
fix(ui): complete stale header outcome ownership (#124442)
* fix(ui): retire stale header outcomes

* test(ui): prove current header outcomes stay visible
2026-08-15 22:56:53 -07:00
Peter Steinberger
e495270319
perf(test): make workshop contention deterministic (#124440) 2026-08-15 22:50:21 -07:00
Peter Steinberger
6aa27d6ecd
refactor: retire August compat windows (embedding API, pi aliases, target parser, spawning hook, setup exports, WhatsApp inbound aliases) (#124416)
* refactor(plugin-sdk): retire embedded Pi aliases

* refactor(channels): retire explicit target compatibility

* refactor(plugins): retire subagent spawning hook

* refactor(plugin-sdk): retire shipped channel setup exports

* refactor(whatsapp): retire inbound callback aliases

Proof: focused build and WhatsApp E2E green; broad WhatsApp suite 188/189 files green. extensions/whatsapp/src/monitor-inbox.policy.test.ts flakes only in the parallel batch and passes isolated (10/10).

* refactor(plugin-sdk): retire memory embedding registrar

Migrate every bundled provider and manifest to registerEmbeddingProvider and contracts.embeddingProviders. Preserve memory-specific batching, local-service acquisition, index identity, and auto-selection through the canonical generic registry adapter, then remove the parallel registrar, registry, diagnostics, contracts, tests, and docs.

* chore(plugin-sdk): tighten retired surface budgets

Pin the post-retirement public SDK surface to 144 entrypoints, 4,312 exports, 2,564 callable exports, and 1,133 deprecated exports; agent-harness-runtime now permits exactly nine deprecated exports.
2026-08-15 22:43:47 -07:00
Eden
a61417fef4
fix(mentions): match decorated identity names (#115278)
Allow group members to type an agent name without optional emoji or symbol decoration while preserving literal separators and Unicode boundaries. Bound raw joiner matching and replay QA startup patches in order.

Co-authored-by: 許元豪 <146086744+edenfunf@users.noreply.github.com>
Co-authored-by: Eden <146086744+edenfunf@users.noreply.github.com>
Co-authored-by: Ayaan Zaidi <hi@obviy.us>
2026-08-16 11:09:03 +05:30
Peter Steinberger
a410ae74f5
fix(agents): defer auth republication to a superseding config publication (#124435)
A runtime auth-store mutation queues an auth refresh task on the prepared
model runtime publication tail. When a config hot reload superseded that
task (markPreparedModelRuntimeSnapshotsStale marks every owner stale and
opens a replacement gate before the queued task runs), the auth task still
ran drainPendingAuthMutations + replyDispatchPublication.rebuild against
the invalidated owners. That either threw
PreparedModelRuntimeOwnerNotPublishedError ('prepared reply dispatch
runtime owner was not published for main'), logging 'auth-triggered model
runtime refresh failed' on every reload and emitting a spurious
phase:'failed' publication event, or announced phase:'published' while the
replacement gate was still pending. The gateway chat metadata lifecycle
listens to those events: a spurious event triggered a metadata refresh
whose captureGenerationFacts saw no published owner (gate pending), failed
with ChatMetadataSnapshotUnavailableError, and runtime.fail() latched the
error while preparedModelRuntimeAvailable=false blocked the subordinate
skills/auth retry path - wedging chat.metadata until restart.

The auth task now fails closed against a pending replacement gate: the
queued config publication owns draining queued auth mutations against the
new config and rebuilding/announcing the dispatch publication
(refreshPreparedModelRuntimeSnapshots already drains the queue before its
own rebuild), so deferring loses nothing.

Regression tests reproduce both failure shapes and fail pre-fix.
2026-08-15 22:36:43 -07:00
Peter Steinberger
255f941065
fix(web-fetch): reject failed provider target statuses (#123741)
* fix(firecrawl): reject failed target statuses

* refactor(firecrawl): remove duplicate scrape cache
2026-08-15 22:35:00 -07:00
Peter Steinberger
982e0181b7
fix(mcp): cancel bundled requests when agent runs stop (#124425)
* fix(mcp): cancel materialized requests

* fix(mcp): keep request cancellation internal

* fix(mcp): type internal request options

* fix(mcp): separate internal request signatures

* fix(mcp): keep runtime factory surface stable

* fix(mcp): preserve optional request methods

* fix(mcp): preserve public runtime contract

* chore(mcp): preserve contributor credit

Co-authored-by: chengzhichao-xydt <chengzhichao-xydt@users.noreply.github.com>

---------

Co-authored-by: chengzhichao-xydt <chengzhichao-xydt@users.noreply.github.com>
2026-08-15 22:28:58 -07:00
Peter Steinberger
1384e277af
refactor(types): enforce chained-assertion guard in AI and UI (#124361)
* refactor(types): drain chained-assertion ledger — ai and ui

* refactor(ui): extract chat state contract

* fix(ai): preserve strict Claude request cleanup

* test(ui): synchronize terminal timeout clock

* fix(ui): validate observer digest before run mutation
2026-08-15 22:25:42 -07:00
Peter Steinberger
78ca5fcfb6
perf(test): fast-forward Slack probe retry window (#124428) 2026-08-15 22:18:20 -07:00
Peter Steinberger
8cf85e3ced
fix: restore release-validation fixture coverage (#124401)
* test(release): refresh validation fixtures

* test(release): satisfy fixture lint gates

* test(release): preserve fixture owner contracts
2026-08-15 22:15:09 -07:00
Peter Steinberger
6335e358f3
fix(ci): keep Crabbox dependencies intact after pnpm dlx (#124423)
* fix(ci): isolate Crabbox pnpm dlx state

* fix(ci): clarify hydrated modules errors
2026-08-15 22:13:26 -07:00
Peter Steinberger
eae415b621
fix(gateway): report pre-launch worker errors (#124387) 2026-08-15 22:10:02 -07:00
Peter Steinberger
203aafc415
feat(lint): SAFETY-comment assertion ratchet + repo deslop skill (#124359)
* feat(lint): add SAFETY-comment assertion ratchet

* feat(skills): add repo deslop skill

* fix(lint): refresh initial assertion baseline

* chore(lint): align assertion baseline with main

* chore(lint): sync baseline with current assertion ledger

* test(ui): stabilize Control UI E2E waits

* chore(lint): sync narrowed assertion ledger

* chore(lint): sync fully drained assertion ledger

* fix(lint): close assertion ratchet bypasses
2026-08-15 22:03:48 -07:00
Peter Steinberger
f1ca5e20d8
perf(test): fast-forward cron receipt handoff (#124417) 2026-08-15 21:50:59 -07:00
Peter Steinberger
345fde4e14
fix(security): align agent roster default audit with runtime semantics (#124398)
A fresh openclaw onboard (and agents add) writes agents.entries without any
default:true marker; runtime resolves the sole agent as default via
tryResolveSoleAgentId, and read-time migration strips valid legacy markers
before the audit ever sees the config. The audit still demanded exactly one
default=true marker on non-explicit rosters, so every fresh install got a
false config.agent_roster.invalid_default_count warning.

Make the audit mirror runtime truth: a non-explicit roster is valid exactly
when the canonical resolver (tryResolveLegacyCompatibilityAgentId) finds an
owner - sole agent, one legacy marker, or the retained migration owner.
Explicit fleets keep the strict no-marker rule. This also fixes the sibling
false alarm for migrated legacy multi-agent configs whose marker was removed
at load time with the owner retained in-process.

Regression test: fresh-install-shaped sole-agent roster produces no roster
finding (fails pre-fix).
2026-08-15 21:50:09 -07:00
Peter Steinberger
0c7b560b23
fix(gateway): avoid repeated session root scans in configured lists (#124384)
* fix(gateway): stop configured session rediscovery

* fix(gateway): reuse prepared child store targets

* refactor(gateway): own prepared session targets

* test(gateway): prove session registry recovery
2026-08-15 21:45:44 -07:00