Preserve the internal null Authorization marker when resolving local no-auth provider headers, avoid classifying LM Studio prompt-template guidance as context overflow, and rebuild ai/llm-core package sources during pnpm dev/watch.
* fix(memory): prune stale session index rows at startup
* fix(memory): reconcile stale sessions without re-embedding
* oc-9df: fail closed on session corpus scan errors
---------
Co-authored-by: Josh Lehman <550978+jalehman@users.noreply.github.com>
Native approval delivery and resolution now stay bound to the originating or explicitly targeted channel account. Unbound requests fail closed across multiple eligible accounts; trusted reviewer-less SDK callers remain compatible.
Co-authored-by: Ayaan Zaidi <hi@obviy.us>
* fix(ui): unify initial prompt handoff projection
Route create-time prompts through the canonical session projection so live persistence and delayed history adopt one stable bubble. Preserve inline attachment content across reconnects and authoritative identity handoff while removing duplicate matching and post-reducer mutation paths.
* fix(ui): preserve initial prompt projection contracts
* fix(ci): restore exact-head validation
* fix(workers): persist placement terminal failures
* fix(workers): refresh placement protocol clients
* refactor(workers): isolate error formatting
* fix: integrate cloud terminal state with current main
* chore(plugin-sdk): refresh API baseline
* refactor(ui): inline one-use cloud terminal-reason banner helper
Keeps the Control UI startup JS bundle inside its 317 KiB gzip budget
(the helper + type-only import tipped it by 16 bytes).
* refactor(ui): trim terminal-reason lookup to type-erased optional access
Recovers the last gzip byte of the Control UI startup budget
(324609 B vs the 324608 B limit).
* fix(security): unify secret-redaction and SSRF policy ownership
Memory-host errors now redact through the canonical redactor (payment/card/CVV
coverage included) via the existing core facade instead of a stale local
pattern table; ACP error redaction is wired through a single barrel so the
injected canonical redactor no longer depends on module load order, and the
acp-core fallback table shrinks to the minimal standalone set (structured
auth-header patterns proven load-bearing stay). The memory-host SsrFPolicy
structural copy is deleted in favor of the canonical src/infra/net/ssrf.ts
type re-exported through the network facade.
* fix(build): keep memory-core doctor closure execa-free
Import the canonical redactor directly from src/logging/redact.js instead of
the openclaw-runtime-io facade (which reaches execa through the full runtime
graph), and regenerate the plugin SDK API baseline for the intentional
canonical-SsrFPolicy surface change.
* fix(security): merge operator redact patterns with defaults in injected redactors
ClawSweeper found that ACP injected the general redactor, where nonempty logging.redactPatterns replace the built-in provider-token patterns. Use the tool-payload redactor for ACP and memory-host error formatting so operator patterns extend defaults and redaction remains forced for these security boundaries.
* fix(plugin-sdk): back every workspace facade export with a real src facade
packages/plugin-sdk declared 59 export subpaths but only 24 had src facade
files; the other 35 defaults pointed at nonexistent ./src/<name>.ts targets
that typecheck (types resolve via boundary dist) but fail runtime resolution.
Create the 35 missing facades (each mirrors the sibling 3-line re-export of
the core src/plugin-sdk entrypoint; all verified live, none retired), and
extend scripts/sync-plugin-sdk-exports.mts to own the facade package too:
exports are regenerated from the src directory, every facade must name a
canonical SDK entrypoint, and --check fails on dangling keys or orphan
facades. The check-changed Plugin SDK surface lane now also triggers on
packages/plugin-sdk/** so the guard actually runs when the map changes.
* fix(plugin-sdk): validate facades before any exports write
ClawSweeper P2: write mode reported a stale facade but still exited 0,
after syncRootPackageExports had already rewritten the root manifest.
Hoist facade validation ahead of all writes and exit nonzero in both
modes; an invalid facade now fails closed with no partial manifest
update (proven: hash-identical manifests plus exit 1 in write mode).
* fix(agents): exclude private shell output from context compaction
## What Problem This Solves
Shell executions explicitly excluded from model context could still contribute their private output to session replay, token estimates, compaction boundaries, or branch summaries.
## Why This Change Was Made
The session projection owner now omits context-excluded shell messages, while compaction assigns those messages zero tokens and prevents private persisted entries from becoming retained-history cut boundaries.
## User Impact
Private shell output remains durably recorded for its intended owner without leaking into model-visible conversation context or wasting compaction budget; legitimate retained context remains intact.
## Context
Actual production code executed in an isolated VM reduced more than 20,000 characters of private output to zero model-visible characters while preserving eligible context. New owner and sibling regressions cover replay, compaction, branch summaries, and token accounting. Existing oxfmt formatting and scoped whitespace checks passed.
* test(agents): cover private Codex history projection
* fix(agents): pair reset tool results within retained session history
## What Problem This Solves
Session resets selected tool-call pairs from history preceding the retained-session boundary, allowing an excluded call to incorrectly claim a retained tool result and leaving replayed conversation history inconsistent.
## Why This Change Was Made
The session-context owner now identifies the retained range before pairing reset tool calls and results. Both reset and compaction flows reuse the same canonical bounded history slice, removing duplicate scan and membership logic.
## User Impact
Reset agent sessions retain only legitimate in-window tool exchanges, repeated resets remain consistent, and cloud-worker replay receives coherent session context without resurrecting discarded calls.
## Context
Actual production-source execution reproduced the previous failure and passed after the fix across valid in-window pairs, repeated resets, and cloud-worker boundaries. Focused session-context and worker-launcher regressions cover the owner and downstream consumer. Existing oxfmt formatting and scoped whitespace checks passed; production code decreases by five lines.
* test(gateway): cover reused reset tool call ids
Worker live events rejected tls_certificate fallback payloads because duplicated closed reason lists had drifted. Establish one canonical dependency-light fallback vocabulary and share its explicit TypeBox schema across worker and cron protocol boundaries.
* feat(memory): support globbed extra paths
Allow root-relative glob patterns on existing memory.search.extraPaths entries across discovery, watching, reindex identity, and QMD migration.
* fix(memory): drop stale lease type import
* fix(memory): enforce extra path glob scope
* feat(gateway): task-suggestion acceptance modes with compact split-button card
- taskSuggestions.accept gains additive mode (worktree default | local | cloud | session) + cloudProfileId; operator.admin unchanged; worktree requests stay {taskId}-only for older gateways
- local reuses the plain-cwd create; cloud mirrors the Control UI create-empty -> sessions.dispatch -> send sequence with pre-claim profile validation and full rollback; session delivers the prompt into the source session (steer single active run, plain turn when idle, ambiguous refused) and can only cancel the chip on failure, never touch the source session
- Control UI card redesigned per owner reference: repo-basename eyebrow, clamped summary, instructions expander, split button with per-profile cloud items or a disabled "No cloud environment configured" hint
- TUI gains the same modes as selector rows with capability gating and double-Enter arming
Release-note context: operators now choose where an accepted follow-up runs — isolated worktree (default), the project checkout, a configured cloud worker, or as the next instruction in the current session — from a compact suggestion card.
* fix(gateway): negotiate task-suggestion acceptance modes and enforce steerable-run invariant
- Gate non-worktree task-suggestion actions on the negotiated Gateway capability.
- Require exactly one steerable run ID before delivering into an active source session.
* fix(opencode): migrate retired free model refs
Repair the shipped beta upgrade path through the provider-owned Doctor contract. Activate the migration from the canonical configured-model selector inventory so every supported selector is covered consistently.
Co-authored-by: samson1357924 <samson1357924@gmail.com>
* fix(opencode): migrate media model preferences
---------
Co-authored-by: samson1357924 <samson1357924@gmail.com>
* feat(gateway): live desktop observer for cloud workers
Adds live observation for cloud worker desktops through the gateway and Crabbox plugin, including desktop provisioning, persisted desktop metadata, tunneled WebSocket proxying, and the worker.desktop.observe protocol method.
The gateway, Crabbox plugin, and gateway protocol surfaces remain off by default behind the cloudWorkers.desktop Labs flag.
* feat(ui): Desktop panel for cloud worker observation
* docs(gateway): document cloud worker desktop lab
* fix(ci): regenerate contract baselines after rebase
* fix(protocol): regenerate Android gateway methods
* fix(ci): align rebased SDK and lint baselines
* fix(gateway): enforce view-only RFB boundary and fence desktop teardown
* fix(gateway): tighten RFB filter surface
* fix(state): keep pre-desktop databases readable and harden view-only RFB
* fix(gateway): fence desktop observer upgrades behind work admission
* fix(gateway): bind desktop observer tokens to their owner epoch
* fix(ci): regenerate config and SDK baselines after rebase
* fix(ci): regenerate native protocol and SDK baselines
* fix(ci): regenerate contracts after main rebase
* fix(state): register desktop metadata as lazy additive
* fix(ci): regenerate SDK baseline after final direct-merge rebase