Commit Graph

1780 Commits

Author SHA1 Message Date
Vincent Koc
e474ba38e8 fix(sqlite): serialize offline maintenance with gateway (#106210) 2026-07-13 18:15:32 +08:00
Peter Steinberger
6cd1133858 feat(cloud-workers): openclaw worker mode running the embedded loop on the box (#105865)
* feat(cloud-workers): add restricted worker runtime

* test(cloud-workers): cover worker runtime contracts

* docs(cloud-workers): document worker mode

* fix(worker): bound connection lifecycle

* fix(worker): serialize transcript flushes

* fix(worker): fail stop stale transcript bases

* fix(worker): degrade lossy live streaming

* test(worker): cover inference reconnect fencing

* refactor(worker): split RPC clients

* refactor(worker): split connection transport

* refactor(worker): split embedded runtime

* refactor(worker): narrow worker module exports
2026-07-13 02:34:31 -07:00
Peter Steinberger
bafabba0df fix(gateway): preserve Control UI turns across restarts (#106151)
* fix(gateway): preserve Control UI turns across restart

* perf(sessions): index restart recovery state

* fix(sessions): avoid replaying pre-admitted turns

* fix(sessions): index per-entry recovery status

* fix(sessions): guard restart failure notices

* fix(sessions): preserve terminal claims across admissions

* fix(sessions): retry failed recovery notices

* fix(sessions): harden restart retry ownership

* fix(gateway): tighten restart recovery typing

* fix(sessions): close restart recovery races

* refactor(sessions): split restart recovery ownership

* chore(sessions): clean restart recovery lint

* chore: drop release-owned changelog entry

* fix(gateway): satisfy restart recovery guards

* test(gateway): cover Control UI durable admission
2026-07-13 02:08:56 -07:00
mushuiyu886
ed57c6cd88 fix(agents): honor claude-cli contextTokens setting (#93198)
* fix: honor claude-cli configured context tokens

* test: cover claude-cli native compaction budget

* test: cover ordinary claude-cli budget persistence

* test: migrate claude-cli budget fixtures to session accessor

* fix(agents): carry CLI provider into context budget

* fix(agents): guard optional CLI context metadata

* fix(agents): align Claude CLI native compaction budget

Co-authored-by: 杨浩宇0668001029 <yang.haoyu@xydigit.com>

* fix(agents): apply selected CLI context cap

Co-authored-by: 杨浩宇0668001029 <yang.haoyu@xydigit.com>

* fix(agents): preserve prepared CLI context budgets

Co-authored-by: 杨浩宇0668001029 <yang.haoyu@xydigit.com>

* fix(agents): resolve prepared CLI context ownership

Co-authored-by: 杨浩宇0668001029 <yang.haoyu@xydigit.com>

* test(agents): type CLI context budget cases

Co-authored-by: 杨浩宇0668001029 <yang.haoyu@xydigit.com>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-13 01:58:44 -07:00
Peter Steinberger
2fc91410e8 refactor: consolidate reconnect supervisors (#105987)
* refactor: consolidate reconnect supervisors

* style: satisfy reconnect supervisor lint

* fix: keep reconnect supervisor internal

* refactor: keep retry supervisor lean

* chore: lower gateway client LOC baseline

* style: satisfy large-file LOC guard

* fix: cap long-lived reconnect backoff

* fix: preserve reconnect start failures

* test(sdk): include retry package in install smoke
2026-07-13 00:39:17 -07:00
Peter Steinberger
0cdb13abfc docs(gateway): dedicated 1Password integration page (#106109) 2026-07-12 23:52:33 -07:00
Peter Steinberger
0633afe6a5 fix(config): reject schema-only keys (#106031)
* fix(config): reject schema-only keys

* chore(config): refresh plugin SDK baseline

* test(config): remove stale remote enabled fixtures
2026-07-12 23:10:12 -07:00
Vincent Koc
f33ab243cf fix(sqlite): reject runtimes vulnerable to WAL corruption (#106065)
* fix(sqlite): require WAL-reset-safe Node runtime

* docs(sqlite): document safe Node runtime floor

* fix(sqlite): defer runtime library validation until use

* fix(ci): align startup memory with Node 24.15
2026-07-13 13:59:00 +08:00
Peter Steinberger
6551786a31 docs: harden Gmail hook guidance 2026-07-12 22:42:48 -07:00
Ayaan Zaidi
6908e6a63b fix(gateway): allowlist default-model config edits and explain protected-path refusals
agents.list[].model was agent-tunable while agents.defaults.model was
refused — the same capability gated by config shape (partially reverts
the defaults-spelling removal from #90145; token/auth/exec paths stay
protected). The bare refusal string also caused agents to misread the
injection boundary as an authorization failure and argue with the owner;
it now states the contract, the remedy, and the agent-tunable paths.
Guard moved to gateway-config-guard.ts (gateway-tool.ts 652->390).

Closes #106059
2026-07-13 11:03:50 +05:30
Peter Steinberger
0d90ca6b5d refactor(config): retire flat and scalar streaming keys from matrix, feishu, and qqbot (#105808)
* feat(doctor): migrate legacy matrix/feishu/qqbot streaming spellings to nested config

* test(matrix): shorten setup fixture tokens below the review secret-scanner threshold

* refactor(config): retire flat/scalar streaming keys from matrix, feishu, and qqbot

* docs: describe nested-only streaming config for matrix, feishu, and qqbot

* fix(qa-matrix): compose nested streaming config for the matrix QA harness

* test(feishu): compose negative webhook fixtures outside the GHSA opengrep pattern

* docs: refresh generated docs map

* test(feishu): compose negative webhook fixtures from lint-clean bases outside the GHSA opengrep pattern

* fix(qa-lab): rewrite crabline flat streaming config into the nested channel shape

* chore(config): regenerate channel config metadata and plugin-sdk API baseline for nested-only streaming

* chore(plugin-sdk): absorb main-side deprecated pairing/conversation pin drift

* fix(qa-lab): consume Crabline nested streaming config
2026-07-12 20:33:14 -07:00
Peter Steinberger
4a05a087a1 refactor(config): retire flat streaming keys from the last six channel schemas via doctor migration (#105709)
* refactor(config): retire flat streaming keys from the last six channel schemas

signal, irc, nextcloud-talk, whatsapp, googlechat, and mattermost now accept
only the nested streaming.{chunkMode,block.enabled,block.coalesce} shape
(mattermost also drops scalar/boolean streaming); flat spellings migrate via
each channel's defineChannelAliasMigration doctor contract with root seeding
for their wholesale-replace account merges.

* feat(channels): warn once per key when the deprecated flat streaming fallback is used

Bundled schemas now reject the flat delivery keys, so the streaming.ts
fallback only serves external SDK plugin configs; emit a once-per-process
per-key subsystem warning and pin the removal plan to the next release train.

* chore(config): regenerate bundled channel config metadata for nested-only streaming

* docs: describe nested-only channel streaming config and the SDK flat-key deprecation window

* fix(whatsapp): seed migrated named-account streaming from the accounts.default layer

WhatsApp resolution layers accounts.default shared config between root and
named accounts, so doctor-materialized account streaming objects now inherit
default-account settings over root ones; mattermost schema test moves to the
nested-only shape with explicit rejection coverage; scope flat-key deprecation
notes to the pending Matrix/Feishu migrations.

* fix(whatsapp): resolve the default account case-insensitively when seeding migrated streaming

* chore(plugin-sdk): repin API baseline for nested-only channel streaming types
2026-07-12 15:27:28 -07:00
Peter Steinberger
5e45ebe82b feat(ios): add private HealthKit summaries (#105616)
* feat(ios): add private HealthKit summaries

* fix(ios): satisfy Health settings lint

* chore(ios): sync Health localization artifacts

* chore(ios): refresh generated localization and docs

* fix(ios): reject partial Health history

* chore(ios): sync Health string catalogs

* fix(ios): bridge Health authorization dates

* fix(ios): scope Health summaries to today
2026-07-12 12:52:38 -07:00
Peter Steinberger
4289c6c16c feat(cloud-workers): replayable worker live-event streaming into the session fanout (#105275)
* feat(protocol): add worker live-event frames

* feat(gateway): fan out replayable worker live events

* feat(gateway): add worker live-event replay receiver

* docs(protocol): document worker live events

* fix(gateway): preserve deferred worker live events

* test(gateway): cover deferred worker event projection

* refactor(gateway): revert async projection layer

* fix(gateway): retain buffered worker live events

* fix(gateway): guard buffered terminal admission

* fix(plugin-sdk): trim worker live-event declarations
2026-07-12 13:47:59 +01:00
Peter Steinberger
dba78584ff fix(ui): preserve rejected first message when session send fails (#105261)
* fix(ui): preserve rejected first session message

* chore: leave changelog to release closeout

* fix(protocol): regenerate session create result
2026-07-12 11:09:38 +01:00
Peter Steinberger
5b56a1f664 feat(gateway): land remaining durable-approvals stack and repair main gates (#104837)
* feat(gateway): propagate approvals to ancestor sessions with replay

Squash-rebased #103921 segment onto the native-clients tip on current main.
Session-scoped approval events publish sanitized pending/terminal
transitions to opted-in session audiences, with authoritative pending
replay on stream subscribe and durable-expiry reconciliation through the
owning manager. SessionApprovalEvent/Replay wire types export from the
approvals owner module; Swift models regenerated.

(cherry picked from commit 2d1dcf9747044710111d0c730fc46ba6013a165c)
(cherry picked from commit ccf88efd56b513d07599ffcee997bf0cddaf9adc)
(cherry picked from commit 8eb33f59f00ec9ee4625259b76bd7ae60d2cd480)
(cherry picked from commit c297cbc93c8401e9c79c20f242245a194f5dd236)
(cherry picked from commit 93d68f28601ff37d863da4db009504993a22533a)
(cherry picked from commit d285ccd8b2f212bb57e814107e7709c896e96b7d)
(cherry picked from commit 5c536982231402b1b58d1683794ea9948b32d077)
(cherry picked from commit 1646e5b6dc4dd20de54e10f110a5909be18d7d50)
(cherry picked from commit 35cf1b705b247fb282f4d56ffe74bd2fb238221f)
(cherry picked from commit 4f8ef3699d)
(cherry picked from commit 74fbdcc99d5fff062d67760a51dba4ee9e84479b)
(cherry picked from commit 222b285502681d2be14b1819798e9ee5555f431e)
(cherry picked from commit b9e744951f676b600e7c5322bfd04b0e99797c07)
(cherry picked from commit 9e904efde5)
(cherry picked from commit 678f2384fa)
(cherry picked from commit 72842e5cf6)
(cherry picked from commit be74c25e80e84a1f065053766f23efb84822e811)
(cherry picked from commit 93ba8c4b09)
(cherry picked from commit 8f23761372)

* feat(gateway): fail-closed plugin and tool approval gates

Squash-rebased #103932 segment onto the ancestor-propagation tip on
current main. Plugin node.invoke approvals claim a one-shot allow-once
decision before handing execution authority to the policy, so observation
or retry cannot replay a consumed approval; sibling tool gates bind
approval ids to their originating reviewer identity.

(cherry picked from commit 122df0d75281f572c012b6484ed5daf085d1d577)
(cherry picked from commit f23d8ac240a8dcf2a42c4daaae962263975a0ae8)
(cherry picked from commit 8632fb6436a224dac7a9a9ef0216884530de2c24)
(cherry picked from commit d9fe2dd5c53665e5732f5f3da5ed1907a686ade8)
(cherry picked from commit bb139f2c8aa36ddad70413e1ef79ff491a6f2ecd)
(cherry picked from commit 9b3e056b68ea515c7d4baef269289b6670570480)
(cherry picked from commit b11e66b59a7af1f3b08712de06864aed64d349e4)
(cherry picked from commit a12916ee592d03dfa35e86a2aaede4476a5d4e5d)
(cherry picked from commit d699de840fc8346892b9ae244fe3c3e8c4413032)
(cherry picked from commit 9b7e5a9608)
(cherry picked from commit 4b507593f1b2f10b4496984c84a2803b853e5c5e)
(cherry picked from commit 56408a186733c4eeb5aa76bd5907cde7b0cd3d5b)
(cherry picked from commit a4051d6d8353d39d6fa0b5d69c36e06c3cd3e796)
(cherry picked from commit 76829805a7)
(cherry picked from commit a8b493f934)
(cherry picked from commit aceb990597)
(cherry picked from commit a29b0e75482470c53a9fb4fe3f204e14cf71868f)
(cherry picked from commit 2e3be08653)
(cherry picked from commit c9ae3d7202)

* fix: main-gate repairs for the durable-approvals stack

- android: capture createdAtMs on the pending exec-approval write at
  registration; canonical readback after a refresh that already replaced
  the visible rows was dropping the approval instead of surfacing the
  still-pending reconciliation message (#104913 merged without this)
- android: generous CI timeout ceilings in GatewayExecApprovalRuntimeTest
- agents: hermetic model-discovery test via the plugins/provider-runtime
  boundary (lazy plugin-runtime resolution hangs vitest workers since #104770)
- cli: usage-cost settle-budget test asserts the budget bound on every call
  instead of pinning the poll count (fast hosts fit a second poll in 50ms)
- protocol coverage: allowlist session.approval for ios/android (native
  review rides exec.approval push/nudge delivery)
- docs map, native i18n inventory, plugin-sdk api baseline regenerated
2026-07-12 10:51:38 +01:00
Peter Steinberger
55254c3a0b feat(nodes): route alerts to the active computer (#105083)
* feat(nodes): route alerts by active computer

* fix(ci): allowlist node presence mobile coverage

* test(prompts): refresh node presence snapshots

* fix(macos): await presence reporter actor hop

* fix(macos): type presence test delivery state

* docs(nodes): add active presence guide

* docs(nodes): format presence troubleshooting
2026-07-12 10:05:50 +01:00
Peter Steinberger
b6c171901e fix(secrets): harden exec provider diagnostics (#105082) 2026-07-12 09:01:33 +01:00
zw-xysk
0b30a3292f docs(slack): fix channel config examples — use 'enabled' instead of 'allow' to match strict schema (#103491)
* docs(slack): fix channel config examples — use 'enabled' instead of 'allow' to match strict schema

* docs(slack): align config reference channel toggle

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-12 08:38:03 +01:00
Peter Steinberger
0086763ba4 feat(fleet): harden create, port allocation, drift visibility, and audit guidance (#104814) 2026-07-12 07:02:42 +01:00
Peter Steinberger
d14bb8ec44 fix: resume replay-safe work after gateway restarts (#104997)
* fix: resume replay-safe work after gateway restart

* chore: leave restart note to release process

* fix: sync restart recovery protocol artifacts
2026-07-12 06:37:22 +01:00
Peter Steinberger
11ea4df29c feat(fleet): per-cell disk limits, egress policy, backup/restore, and cell diagnostics (#104828)
* feat(fleet): per-cell disk limits, egress policy, backup/restore, logs, and doctor

- fleet create --disk <size> caps the container writable layer via --storage-opt;
  unsupported storage backends fail create with an actionable support-matrix
  error, and the limit replays across upgrade/restore through a fleet-owned
  container label because Podman inspect has no HostConfig.StorageOpt.
- fleet create --network bridge|internal adds an opt-in no-egress mode on
  Podman (published loopback port keeps working, verified live); Docker
  internal cells are rejected fail-closed because Docker does not publish
  loopback ports on internal networks.
- fleet backup/restore: per-tenant 0600 tar archives with manifest tenant
  binding, symlink/hardlink rejection, byte and path-segment budgets,
  root-bounded extraction, atomic no-overwrite publish, lease fencing, and
  Gateway token rotation on restore; failures preserve displaced data and
  never leave a force-stopped or half-started cell serving silently.
- fleet logs: ownership-asserted, bounded, token-redacted on both streams,
  with a generation re-check so a concurrent restore cannot leak a rotated
  token.
- fleet doctor: read-only per-cell audit of ownership labels, health,
  hardening drift, loopback port binding, token presence, network egress
  mode, and 0700 state-dir permissions; any failed finding exits nonzero.
  Cross-runtime checks are grounded in live-verified Docker 28/Podman 4.9
  inspect shapes (CapDrop vs EffectiveCaps, missing StorageOpt, missing
  network containers map).

Related: #104436 (v1 shipped in #104527)

* fix(fleet): harden streamed log redaction and root restore ownership

- redacting stream writer honors target backpressure, retains secret-prefix
  overlap across forced long-line flushes, and never splits a token between
  emitted chunks
- root-invoked restores repair ownership for explicit non-root user mappings
  instead of leaving root-owned 0700 state trees
- fleet logs merges the shipped --follow streaming surface (#104669) with the
  v1.1 token-redaction contract

* fix(fleet): stream partial log lines live and report phase-accurate restore recovery paths

- the redacting log writer emits safe text on every chunk (retaining only a
  possible token prefix) so unterminated progress output streams immediately
- restore failure notes distinguish pre-swap, displaced, and swapped states so
  operators recover the correct tree, and an unavailable runtime inspection is
  reported as an unverified replacement instead of silence

* fix(fleet): reject backslash archive paths, guard stderr pipes, and validate disk-limit labels in doctor

- restore/backup path rules reject literal backslashes so a tampered entry
  cannot validate as one path and extract as another on POSIX
- fleet logs handles broken pipes on stderr as well as stdout
- fleet doctor fails malformed disk-limit labels that would break
  upgrade/restore replay instead of reporting them as passing
2026-07-11 18:24:01 -07:00
Peter Steinberger
508f6a2996 refactor(config): retire legacy flat streaming keys to doctor-owned migration (#104693)
* chore(config): regenerate bundled channel config metadata for retired flat streaming keys

* refactor(config): retire legacy flat streaming keys to doctor-owned migration

* fix(config): restore zod locale installer dropped in rebase and repin SDK surface
2026-07-11 18:15:03 -07:00
Peter Steinberger
04f945fabe feat(cloud-workers): durable transcript commit protocol for worker sessions (#104809)
* feat(cloud-workers): add transcript commit protocol

* feat(cloud-workers): persist transcript commit replay state

* feat(cloud-workers): apply transcript commits to sessions

* fix(cloud-workers): harden transcript commit admission

* fix(cloud-workers): recover branched transcript commits

* fix(cloud-workers): preserve diagnostic semantics
2026-07-11 17:29:07 -07:00
snowzlmbot
be373ea516 improve(android): show provider-configured model details (#101912)
* feat(android): show provider model inventory

Co-authored-by: snowzlmbot <293528334+snowzlmbot@users.noreply.github.com>

* fix(gateway): project provider inventory routes

* style(android): satisfy provider inventory ktlint

* chore(android): sync provider inventory i18n

* style(android): finish provider inventory formatting

* fix(android): harden provider inventory refresh

* test(gateway): type provider inventory fixture

* chore(protocol): regenerate Swift model choice

* chore(android): sync provider inventory i18n

* test(gateway): pin provider inventory discovery mode

* chore(android): sync provider inventory landing

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: snowzlmbot <293528334+snowzlmbot@users.noreply.github.com>
2026-07-11 17:22:16 -07:00
Peter Steinberger
02dc25a1b5 feat(gateway): persist operator approvals (#103579)
* feat(gateway): persist operator approvals

* fix(gateway): preserve approval ids exactly

* fix(gateway): enforce approval reviewer bindings

* fix(gateway): reconcile durable approvals with exec revocation hardening

Map #103515 semantics onto the durable lifecycle: resolutionSource and
one-shot consumeAskFallback stay process-local record facts, trusted
auto-review resolves through the durable CAS as a runtime resolver, and
lost races settle with the winner's operator source. Also: derive the
audience walker cap from the store cap, report APPROVAL_ALREADY_RESOLVED
for a resolve that loses the CAS race, document approval.get/resolve in
the protocol docs, and regenerate Swift models on the new base.

* fix(approvals): validate resolver kind

* docs(approvals): explain malformed verdict denial

* fix(protocol): regenerate approval models after rebase

* chore: leave changelog entry to release generation

* fix(gateway): preserve approval registration boundaries

* test(gateway): prove multi-device approval races

* test(gateway): keep approval order assertion stable

* docs: index operator approval architecture

* fix(protocol): bound approval declaration exports
2026-07-11 16:53:49 -07:00
pick-cat
3d3796243f docs(gateway): add launchd supervisor loop troubleshooting (#89816)
* docs(gateway): add launchd supervisor loop troubleshooting

* docs(gateway): warn before disabling node LaunchAgent

* chore: trigger CI after rebase onto main

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* docs(gateway): modernize launchd recovery runbook

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-11 15:59:12 -07:00
Peter Steinberger
1b1cebfe42 fix(openai): align auth availability with effective routes (#104685)
* feat(openai): add provider-owned route facts

* fix(openai): harden provider route facts

* test(codex): update rebased auth fixtures

* chore: leave release notes to release workflow

* fix(openai): align route auth with current contracts

* test(openai): align route and shard expectations

* test(openai): satisfy route fixture contracts

* fix(openai): preserve direct profile forwarding

* test(models): complete route auth mocks

* test(codex): type compaction factory mock

* fix(openai): preserve provider-native model ids

* test(agents): align route auth fixtures

* style(agents): format route integrations

* test(plugin-sdk): pin current surface counts
2026-07-11 15:26:48 -07:00
Ho Lim
8a4463eef1 feat(browser): support evaluate timeouts for existing sessions (#103181)
* fix(browser): honor evaluate timeout for existing sessions

Signed-off-by: Ho Lim <subhoya@gmail.com>

* docs(browser): align existing-session evaluate timeouts

---------

Signed-off-by: Ho Lim <subhoya@gmail.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-11 15:23:52 -07:00
Josh Lehman
0a8e3604ba refactor: flip sessions and transcripts to sqlite storage (#98236)
* refactor(sessions): migrate runtime storage to sqlite

* test(sessions): fix sqlite CI regressions

* test(sessions): align remaining sqlite fixtures

* fix(codex): require sqlite trajectory recorder

* test(sessions): align orphan recovery sqlite fixture

* test(sessions): align sqlite rebase fixtures

* fix(sessions): finish current-main integration of the sqlite flip

Resolve the whole-store SDK removal across its owner boundary: drop the
loadSessionStore re-export and the registry whole-store wrappers, wire
hasTrackedActiveSessionRun into gateway chat, complete the
preserveLockedHarnessIds cleanup contract, flip the codex thread-history
import to storePath targets, and port remaining main-side tests from
file-store helpers to session accessor reads.

* chore: drop committed pebbles log, revert plugin-inspector bump, refresh generated docs

Remove the 1.8k-line .pebbles/events.jsonl work log from the branch, restore
the plugin-inspector advisory lane to main's pinned 0.3.10 so the supply-chain
bump gets its own review, and regenerate docs_map, the plugin SDK API baseline,
and the export-surface ratchet for the merged tree.

* feat(sessions): keep archived transcripts by default with zstd cold storage

Codex-style retention: deleting or resetting a session archives its
transcript as a zstd-compressed JSONL artifact (plain when the runtime
lacks node:zlib zstd) and keeps it until the disk budget evicts oldest
first. resetArchiveRetention now governs both deleted and reset archives
and defaults to keep; maxDiskBytes defaults to 2gb so retention stays
bounded, with archives evicted before live sessions. The cron reaper
follows the same knob instead of deleting archives on its own timer.

* fix(state): converge agent DB migration lineages and bound database growth

Merge coherence: run both structure-gated legacy memory-schema repairs
(flip-lineage drop, main-lineage identity rebuild) before the flip
migration so pre-flip v1/v2 and pre-merge flip v1/v4 databases all
converge, and hoist foreign_keys=OFF outside the schema transaction
where the pragma was silently ignored and the v1 sessions rebuild
cascade-deleted session_entries.

Growth guards: fresh agent DBs enable auto_vacuum=INCREMENTAL, WAL
maintenance releases freed pages in bounded passes (never a blocking
full VACUUM), and doctor reports state/agent DB bloat from freelist
stats.

* fix(codex): resolve the store path for thread-history import via the SDK

The supervision catalog passed the legacy sessionFile locator to the
storePath-targeted transcript mirror; resolve the agent store path with
the session-store SDK helper instead of a runtime-object seam so test
fakes and headless callers need no extra surface. Drop the obsolete
missing-session-id preprocessing case: sessions rows are NOT NULL on
session_id and upsert repairs id-less patches at write time.

* fix(sessions): fail safe on malformed disk-budget config and doctor stat errors

A malformed explicit maxDiskBytes disables the budget instead of
falling back to the destructive 2gb default the user never chose, and
the doctor bloat check skips databases whose paths stat-fail instead of
aborting doctor.

* fix(sessions): complete sqlite conflict translations

* test(sqlite): align hardening checks with maintenance

* test(sessions): inspect compressed transcript archives

* fix(tests): await session seeds and drop unused helpers flagged by CI lint

The five unawaited writeSessionStoreSeed calls raced their SQLite seeds
against the assertions, failing compact shards; the bloat probe drops a
useless initializer and the merged tests drop now-unused helpers.

* test(sessions): type legacy proof events directly

* test(sessions): align hardening contracts

* perf(sessions): read usage transcript sizes from SQL aggregates

Usage/cost scans walked every session and materialized every transcript
event just to re-stringify it for a byte estimate — the #86718 stall
class reborn on the DB. readTranscriptStatsSync sums stored JSON bytes
in SQLite without loading a single row.

* fix(sessions): re-root foreign-root transcript paths onto the current sessions dir

Restored backups, moved OPENCLAW_STATE_DIR, and rehearsal copies carry
absolute sessionFile paths from the old root; the containment fallback
kept those foreign paths, so migration read (and would archive) files in
the original root and reported local copies missing. Re-root the
canonical agents/<id>/sessions suffix onto the current dir when the file
exists there; genuine cross-root layouts still fall through unchanged.

* test(agents): seed harness admission through sqlite

* fix(sqlite): close agent db on pragma setup failure

* fix(doctor): compact and retrofit incremental auto-vacuum after session import

The migration is the sanctioned offline window: post-import compact
reclaims import churn and applies auto_vacuum=INCREMENTAL to databases
created before the fresh-DB pragma existed, so runtime maintenance can
release pages in bounded passes on every install.

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-11 14:50:37 -07:00
Peter Steinberger
b80ab618c3 feat(cloud-workers): authenticated worker protocol with closed ingress and minted credentials (#104688)
* feat(cloud-workers): add authenticated worker protocol

* feat(cloud-workers): add worker credential primitives

* docs(gateway): document closed worker protocol

* test(cloud-workers): keep protocol fixtures lean

* fix(cloud-workers): bound live worker connections

* fix(cloud-workers): close admission and cleanup gaps

* docs: regenerate docs map for worker protocol page
2026-07-11 13:45:14 -07:00
Peter Steinberger
7a466b33f3 feat: add metadata-only message audit events (#103903)
* feat: add metadata-only message audit events

* chore(protocol): restore generated swift models and config baseline after rebase

* fix(state): gate agent-db ownership check before schema version

* fix(cli): sync audit command description into the root-help catalog

* fix(audit): require destination proof before classifying outbound messages as direct

* refactor(audit): drop dead migration guard and add contract comments

* docs(gateway): add dedicated audit history page and cross-links

* test(e2e): enable direct-mode message audit in the telegram proof SUT config

* test(channels): expect declared conversationKind in durable delivery session context

* fix(audit): record the routing channel id for inbound rows from plugin channels

* fix(audit): match channel-prefixed delivery targets in the destination route gate

* fix(audit): validate explicit target kind against the destination route kind

* fix(audit): use the canonical target-prefix grammar in the destination route gate and fail closed on foreign migration tables

* fix(audit): normalize nested provider and kind target prefixes in the destination gate

* fix(audit): strip registered provider aliases and the direct kind prefix in the destination gate

* chore(docs): refresh config baseline after rebase
2026-07-11 13:14:08 -07:00
NIO
589f1c00de feat(security): audit open ingress control-plane tool exposure (#100965)
* fix(security): audit open control-plane exposure

Co-authored-by: NIO <nocodet@mail.com>

* chore: keep sweep changelog neutral

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: NIO <nocodet@mail.com>
2026-07-11 12:36:37 -07:00
Shakker
cc07451a57 docs: document centered chat layout 2026-07-11 20:33:52 +01:00
Peter Steinberger
5a5424474d feat(fleet): multi-tenant hosting via openclaw fleet cell supervisor (#104527)
* feat(fleet): add openclaw fleet cell supervisor for multi-tenant hosting

* test(fleet): cover cell profile, registry, containers, and service flows

* docs(fleet): document multi-tenant hosting and the fleet CLI

* fix(fleet): verify upgrade replacements and release foreign-collision reservations

* fix(fleet): gate upgrade commit on replacement health

* docs(fleet): mark fleet experimental and pin its single-host scope

* test(fleet): make incomplete-profile casts explicit for test-type lane

* fix(state): regenerate kysely schema artifacts after rebase conflict
2026-07-11 11:24:04 -07:00
Peter Steinberger
49b5b862ac feat: node-hosted plugins — dynamic tools, MCP servers, and skills (#90431)
* feat: node-hosted plugins — dynamic tools, MCP servers, and skills

Nodes become declarative plugin hosts:
- node.pluginTools.update: node hosts publish plugin-registered agent tool
  descriptors; gateway materializes them as agent tools executing via
  node.invoke under the node command allowlist, with tools.effective
  invalidation and node online/offline removal.
- Trusted paired-node descriptors: no gateway-side plugin registration
  required; gateway.nodes.pluginTools.enabled off-switch (default on);
  description/count caps; deterministic node-prefixed collision names.
- Declarative node-hosted MCP: nodeHost.mcp.servers (McpServerConfig shape)
  starts MCP clients on the node host, publishes tools as pluginId node-mcp,
  executes via built-in mcp.tools.call.v1 with per-layer timeouts, failure
  isolation, and orphan-safe shutdown. No re-pairing when servers change.
- Node-hosted skills: node.skills.update publishes ~/.openclaw/skills
  content (64 skills/64KB/512KB caps both sides); gateway merges them into
  the skills snapshot while connected and exec host=node is available, with
  node:// locators, node-prefixed collisions, disabled command dispatch,
  and gateway.nodes.skills.enabled + nodeHost.skills.enabled switches.
- Security: node-supplied pluginIds cannot satisfy pluginId-scoped tool
  allowlists unless gateway-registered; reserved node-mcp id requires the
  core MCP descriptor shape; protocol registry kept out of public
  plugin-sdk dts.
- E2E: pond harness proves publication, MCP round-trip, skills locator, and
  disconnect/reconnect for all three surfaces.

* style: format node-plugin-tools test

* fix(skills): keep status loader unfiltered when eligibility is passed

skills.status started passing eligibility for the node-skill merge, which
flipped loadWorkspaceSkillEntries into filtered mode and dropped disabled
skills from status reports (QA plugin-lifecycle-hot-reload timeout). Status
now merges node skills explicitly around an unfiltered load. Also: regen
docs_map for new node docs sections; add the intentional node-host MCP
onclose suppression to the lint-suppression allowlist.
2026-07-11 10:16:34 -07:00
Peter Steinberger
5ca46a6554 feat(cloud-workers): pinned SSH tunnel runtime and provider-owned key resolution (#104553)
* feat(cloud-workers): add pinned SSH tunnel runtime

* feat(crabbox): resolve cloud worker SSH identities

* docs(cloud-workers): document SSH tunnel contracts
2026-07-11 09:26:08 -07:00
Kevin Lin
b769964e82 feat(codex): support workspace-directory plugins (#104188)
* feat(codex): support workspace directory plugins

* fix(codex): contain workspace catalog failures

* chore(config): refresh documentation baseline
2026-07-11 09:04:55 -07:00
Peter Steinberger
03cab29505 feat(cloud-workers): worker bundle production, pinned SSH bootstrap, and admission handshake (#104532)
* feat(gateway-protocol): add worker admission handshake

* feat(cloud-workers): build and bootstrap worker bundles

* feat(cloud-workers): wire bootstrap lifecycle

* fix(cloud-workers): state host-key TOFU fallback without warning-comment suppression

* test(cloud-workers): assemble host-key fixture to satisfy review secret scanner

* test(cloud-workers): assemble redaction fixture to satisfy review secret scanner

* fix(cloud-workers): require pinned SSH host keys

* fix(state): add ssh_host_key to additive worker_environments migration
2026-07-11 08:14:30 -07:00
Peter Steinberger
fa77fe10d5 chore: migrate active GPT-5.5 references to GPT-5.6 (#104452)
* chore(models): migrate active GPT-5.5 references

* test(workboard): expect GPT-5.6 Sol default

* chore: keep release notes in PR body

* test(models): align picker fixtures with Sol default

* test: update PDF default model expectation

* test(qa): migrate thinking smoke to Luna

* test(gateway): align mock catalog with Sol default

* ci: retrigger exact-head PR checks

* test(gateway): document default catalog invariant
2026-07-11 06:30:57 -07:00
Peter Steinberger
e681646834 feat(cloud-workers): add crabbox worker provider plugin and profile-aware lease lifecycle (#104465)
* feat(cloud-workers): add Crabbox worker provider

* docs(cloud-workers): document Crabbox profiles

* chore(cloud-workers): drop changelog entry (release-only file)

* refactor(plugin-sdk): pass profiles to worker lease lifecycle

* docs(plugin-sdk): document worker lifecycle profiles

* chore(docs): regenerate plugin inventory, docs map, and sdk baseline after rebase

* fix(cloud-workers): state crabbox key-ref gap without warning-comment suppressions
2026-07-11 05:51:56 -07:00
Peter Steinberger
90e465833b feat(gateway): durable cloud worker environments, provider SDK contract, and lifecycle RPCs (#104401)
* docs(plan): add cloud workers design plan

* feat(plugin-sdk): add cloud worker provider foundations

* feat(protocol): add worker environment lifecycle shapes

* feat(gateway): persist worker environment lifecycles

* test(gateway): pin environment inventory assertion for damaged worker store

* style(cloud-workers): satisfy lint and docs formatting

* fix(gateway): narrow worker environment type boundaries

* chore(plugin-sdk): account for WorkerProvider surface growth

* docs: regenerate docs map
2026-07-11 04:54:27 -07:00
Peter Steinberger
2d319961d5 fix(browser): block interaction-triggered navigation SSRF (#104254)
* fix(browser): guard interaction navigation requests

* fix(browser): preserve pages on blocked navigation

* fix(browser): enforce interaction navigation policy

* test(browser): type navigation guard fixtures

* fix(browser): execute guarded wait predicates

* style(browser): satisfy interaction lint

* fix(browser): guard hover drag and scroll navigation

* fix(browser): type policy check outcomes

* test(browser): type navigation guard mocks

* fix(browser): preserve proxy policy for guarded interactions

* fix(browser): carry navigation policy through actions

* fix(browser): retain policy for existing-session guards

* fix(browser): guard existing-session waits

* test(browser): avoid shadowed guard pages

* fix(browser): expose scroll action to agents

* fix(browser): disable speculative managed preconnects

* docs(browser): bound managed preconnect hardening

* fix(browser): keep wait behavior outside interaction guards

* chore(browser): leave release notes to release automation

* fix(browser): guard all interaction navigations
2026-07-11 04:30:33 -07:00
Vincent Koc
4dc4115157 docs: cover embedding local service leases 2026-07-11 16:22:22 +08:00
NianJiu
54eda58447 fix(gateway-client): stop unbounded requests masking stalled transports (#103407)
* fix(gateway-client): keep watchdog active for unbounded requests

* test(gateway-client): prove watchdog recovery lifecycle

* style(gateway-client): satisfy watchdog test lint

---------

Co-authored-by: NianJiuZst <180004567+NianJiuZst@users.noreply.github.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-11 00:27:34 -07:00
Peter Steinberger
f94a7dc183 feat(codex): supervise native Codex sessions (#104045)
* feat(codex): add native session supervision

* fix(codex): harden supervision integration

* fix(codex): preserve locked harness ownership

* fix(codex): fence native session archive

* fix(codex): revalidate archive binding ownership

* feat(codex): integrate supervision runtime

* feat(sessions): preserve harness-owned execution

* feat(sessions): persist harness ownership invariants

* feat(gateway): enforce harness-owned sessions

* feat(setup): enable detected Codex supervision

* feat(mac): expose supervised Codex sessions

* feat(ui): make Codex sessions actionable

* docs(codex): document session supervision

* test(codex): cover integration ownership

* chore(i18n): refresh supervision inventories

* fix(setup): finalize Codex activation atomically

* test(codex): narrow binding store update

* fix(sessions): preserve legacy model locks

* test(macos): serialize Codex catalog fixtures

* fix(sessions): preserve legacy lock admission

* chore(i18n): reconcile supervision metadata

* test(sessions): mark legacy lock fixture

* fix(macos): drain final Codex catalog frame

* docs: leave supervision note to release

* style(macos): satisfy Codex catalog type length

* chore: record session accessor seam owners

* fix(macos): honor configured Codex supervision

* fix(codex): preserve harness-owned model locks

* fix(codex): satisfy supervision lint gates

* chore(i18n): refresh native supervision inventory

* fix(codex): align supervision validation contracts

* fix(codex): close supervision boundary gaps

* fix(codex): preserve supervision activation contracts

* fix(codex): dispose standalone supervision runtime

* fix(codex): pin supervised source connection

* fix(plugins): bind delegated runs to exact session target

* fix(codex): scope supervised sessions to configured agents

* fix(codex): fingerprint effective supervision home

* fix(codex): normalize supervision plugin policy

* fix(codex): keep supervised bindings stable across upgrades

* fix(codex): guard all supervised binding connections

* fix(codex): preserve catalog filters and pending CAS identity

* fix(codex): preserve supervision identity for diagnostics

* fix(codex): bind uncertain commits to supervision connection

* fix(codex): satisfy supervision type boundaries

* fix(macos): reconcile current main validation

* fix(codex): handle absent runtime config in supervision

* fix(doctor): own local audio acceleration check

* fix(codex): satisfy integration lint gates

* fix(codex): satisfy lifecycle safety guards
2026-07-11 00:12:08 -07:00
Peter Steinberger
dfa31af0d4 docs(plugins): document safe external cron projection (#104227)
* docs(plugins): document safe cron projection

* docs(plugins): serialize cron projection revisions

* docs: refresh generated map

* docs(plugins): cancel stale cron projections
2026-07-10 23:26:40 -07:00
Peter Steinberger
02cd9bf648 fix: suspension and restart wait for background execs (#104172)
* fix: block restart and suspension on background execs

* test: cover background exec suspension inspector
2026-07-10 22:56:17 -07:00
Peter Steinberger
35d6077db8 fix(gateway): admit plugin HTTP work during suspension (#104112)
* fix(gateway): admit plugin HTTP work during suspension

* test(gateway): remove unused suspension import

* docs: keep release notes in PR metadata

* fix(gateway): scope suspension route bypass
2026-07-10 22:34:57 -07:00
Peter Steinberger
58b0ec9e50 feat(gateway): auto-approve node pairing via SSH device-key verification (#104180) 2026-07-10 22:23:10 -07:00