Commit Graph

39 Commits

Author SHA1 Message Date
Peter Steinberger
568ea29d2e refactor(plugins): inherit shared package boundary settings (#117474) 2026-08-01 09:11:09 -07:00
Miorbnli
0d8b70f39e fix(channels): strip internal tool text in Reef and Zalo Personal (#112621) 2026-08-01 02:10:19 -07:00
Ayaan Gazali
11069c3df5 fix(channels): config validation rejects documented channels.<id>.configWrites on 13 channels (#117206) 2026-08-01 15:33:16 +08:00
Peter Steinberger
9e4381eb1c refactor(channels): unify bundled channel setup contracts (#117106)
* refactor(channels): canonicalize bundled setup contracts

* test(matrix): use scoped environment fixtures
2026-07-31 16:57:29 -07:00
Vincent Koc
007fdb1f7c test(extensions): remove duplicate coverage (#116643) 2026-07-31 11:59:12 +08:00
Vincent Koc
5504f1e9a1 test(reef): remove false-green live guard smoke (#116393) 2026-07-30 20:16:28 +08:00
Peter Steinberger
302f262e6b refactor: deduplicate extension normalization primitives (#115650)
* refactor(plugins): reuse SDK normalization primitives

* fix(ci): repair code-mode matrix checks

* fix(ci): satisfy code-mode matrix gates

* fix(ci): use matrix evidence export

* fix(ci): validate matrix evidence artifact
2026-07-29 04:10:06 -04:00
Jesse Merhi
d7627d6f4c refactor(prompt): use plain inbound context labels and drop system-tag sanitizer (#112000)
* refactor(prompt): plain inbound context labels with a provenance marker

Replaces trust-worded inbound context labels ("(untrusted metadata)",
"(untrusted, for context)") with plain labels plus a fixed provenance
marker suffix appended to every OpenClaw-injected context header.

Detection keys on the marker, not label text, so strippers stay correct
across UI, TUI, replay, /trace segmentation, memory recall, and the Swift
chat preprocessor. Drops sanitizeInboundSystemTags in favor of the marker
boundary plus trusted system-prompt narration.

Renames the untrusted-named plugin SDK context identifiers to
channel-provenance names, keeping deprecated aliases registered for
removal after 2026-09-08.

Adds `openclaw doctor --fix` migrations that rewrite legacy inbound
labels in stored SQLite transcripts and purge legacy envelope-
contaminated LanceDB recall rows.

* fix(ci): resolve gate failures for plain inbound context labels

- doctor sqlite readers: open read-only connections via openNodeSqliteDatabase
  so the Kysely connection-boundary guardrail holds; unexport the now-internal
  transcript snapshot type (Knip unused-export gate).
- compat registry: split the record table into registry-records.ts and
  plugin-sdk-subpath-records.ts. The new compat record pushed registry.ts past
  the 700-line oxlint cap; suppressions are disallowed, so follow the existing
  sibling record-module pattern. Public exports and PluginCompatCode literals
  unchanged.
- acp-runtime test: assert current finalization behavior (newline normalization
  only). The bracket de-fang and System: rewrite it expected were removed with
  sanitizeInboundSystemTags; forged system lines are neutralized at the
  system-event queue, the single chokepoint feeding the System:-per-line render.
- regenerate docs_map and the plugin SDK API baseline manifest.

* fix(prompt): harden inbound context label migration and drop in-band sanitizer

Review follow-ups on the plain-label + provenance-marker change:

- Remove src/security/system-tags.ts. Rewriting inbound text to neutralize
  look-alike `System:`/`[System]` markers corrupted legitimate user text and is
  not a real injection boundary; role separation plus external-content wrapping
  is. Explicit product decision, recorded at the system-event queue.
- Narrow the LanceDB legacy-row purge so it cannot delete benign memories. It
  now requires a complete known legacy sentinel line, a legacy label followed by
  a fenced JSON body, or the complete legacy external-content header. The prior
  predicates matched ordinary prose such as `Notes (untrusted metadata):`, and
  deletion is irreversible.
- Make explicit-empty canonical ChannelStructuredContext win over the deprecated
  alias via a present/absent result instead of collapsing `[]` to undefined.
- Keep `\r?` in the active-memory doctor rule. It is the only rule spanning the
  header's line break, migrated assistant rows skip newline normalization, and
  without it the marked-header replace wins and the body strips to empty. Added
  a CRLF regression test.
- Fix stale comments that described removed behavior, and cover the Swift
  prose-block strip path.

Claude-Session: https://claude.ai/code/session_01WNzsPddQmxy9Y7jKD4wAxH
2026-07-27 11:27:53 +10:00
Peter Steinberger
d6971f46ca fix: make filesystem publication crash-durable (#113453)
* fix(fs): centralize directory durability

* chore: keep release notes in PR body

* test(sqlite): canonicalize read-only race paths

* test(fs): clean durability fixtures

* chore(lint): prune sqlite snapshot baseline

* fix(backup): reject unsupported commit sync

* fix(fs): enforce strict durability outcomes

* refactor(tls): flatten preserved-output failures

* fix(reef): require durable journal commits

* fix(fs): route durability through policy boundaries

* fix(reef): preserve Windows journal compatibility

* fix(fs): bind publication to canonical directories

* fix(ci): align durability boundary fixtures
2026-07-24 20:58:17 -07:00
Peter Steinberger
acd92f6a3d chore(deps): refresh repository dependencies (#112453)
* build(deps): update QA broker dependency

* build(deps): refresh repository dependencies

* build(deps): reconcile rebased shrinkwraps

* test(plugins): remove stale loader test state

* test(deps): stabilize updated dependency coverage

* fix(swift): use caller-isolated TaskLocal overload

* build(deps): regenerate rebased shrinkwraps

* test(msteams): preserve DNS validation in fetch helper

* fix(deps): avoid vulnerable optional image stack

* test(deps): validate generated LRU override

* refactor(ui): extract chat resizable divider

* test(ui): update divider ownership path

* fix(matrix): retain restart-compatible SDK

* style(cron): format update test
2026-07-23 16:17:13 +00:00
Jesse Merhi
4a2a600809 feat(channels): add channel-owned setup contracts (#112176)
* feat(channels): add channel-owned setup contracts

* test(channels): align legacy setup fixtures

* chore(channels): regenerate config and SDK baselines after rebase

* fix(update): run fresh doctor after current-process core changes

* fix(channels): align add pre-scan with execution precedence

* style(cli): format channels-cli test additions

* fix(channels): restore option-before-positional channel resolution via metadata arity scan

* fix(channels): keep help flags out of metadata arity escalation

* test(update): mock fresh post-update doctor in current-process suites

* style: format review fixes and correct entrypoint mock type

* fix(channels): register only modern contract options for dual-publishing plugins

* test(update): align downgrade suites with fresh-doctor child invocation

* docs(channels): record empty-contract and input-forwarding invariants

* fix(line): keep the shipped --token switch as a channel access token alias

* fix(signal): stop treating exact cross-family loopback endpoints as bind-aligned

* chore(config): regenerate docs config baselines after second rebase

* style: format rebased channels add tests

* fix(channels): enforce field-key and flag-name agreement in setup contracts

* fix(signal): detect container endpoints for bare --http-url setup

* fix(signal): ignore unconfigured accounts in transport collision checks

* fix(channels): validate negated setup flags in contract and normalizer

* fix(signal): preserve existing transport kind when setup detection is unreachable

* style(signal): use direct boolean check in collision guard

* style(signal): type test config literals

* docs(update): record two-read design of fresh-doctor validation gate

* fix(channels): satisfy post-rebase architecture gates

* docs: refresh channel setup map

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-22 19:57:42 -04:00
Peter Steinberger
edecdbd05e refactor(config): config-surface reduction tranche 3 — product consolidations (review request) (#111527)
* refactor(config): consolidate media model lists

* refactor(config): unify memory configuration

* refactor(config): consolidate TTS ownership

* refactor(config): move typing policy to agents

* refactor(config): retire product-level config surfaces

* refactor(config): share scoped tool policy type

* chore(config): refresh generated baselines

* fix(config): honor agent typing overrides

* fix(config): migrate sibling config consumers

* refactor(infra): keep base64url decoder private

* fix(config): strip invalid legacy TTS values

* chore(config): refresh rebased baseline hash

* fix(doctor): route legacy messages.tts.realtime voice to talk during tts move

* refactor(config): polish final layout names

* refactor(config): freeze retired tuning defaults

* feat(config): add fast mode default symmetry

* refactor(config): key agent entries by id

* docs(config): update final layout reference

* test(config): cover final layout migrations

* chore(config): refresh final layout baselines

* fix(config): align final layout runtime readers

* fix(config): align remaining readers

* fix(config): stabilize final layout migrations

* fix(config): finalize config projection proof

* fix(config): address final layout review

* docs(release): preserve historical config names

* fix(config): complete keyed agent migration

* fix(config): close final migration gaps

* fix(config): finish full-branch review

* fix(config): complete runtime secret detection

* fix(config): close final review findings

* fix(config): finish canonical docs and heartbeat migration

* fix(config): integrate latest main after rebase

* refactor(env): isolate test-only controls

* refactor(env): isolate build and development controls

* refactor(env): collapse process identity indirection

* refactor(env): remove duplicate config and temp aliases

* docs(env): define the operator-facing allowlist

* ci(env): ratchet production variable count

* fix(env): remove stale provider helper import

* fix(env): make ratchet sorting explicit

* test(env): keep test seam in dead-code audit

* test(env): cover ratchet growth and boundary; document surface budgets

* docs(config): document tier-eval consolidations

* docs(config): clarify speech preference ownership

* test(memory): align retired tuning fixtures

* refactor(memory): freeze engine heuristics

* refactor(config): apply tier-eval tranche

* refactor(tts): move persona shaping to providers

* refactor(compaction): move prompt policy to providers

* test(config): align hookified prompt fixtures

* chore(deadcode): classify test-only exports

* chore(github): remove unused spawn helper

* chore(deadcode): classify queue diagnostics

* chore(deadcode): remove unused lane snapshot export

* chore(plugin-sdk): ratchet consolidated surface

* fix(config): integrate latest main after rebase
2026-07-21 20:28:43 -07:00
Jesse Merhi
ce9e393196 fix: make Back work within channel setup (#108007)
* fix: support Back within channel setup

* docs: note channel setup Back navigation

* fix: keep navigation outcome type private

* style: format navigation outcome type

* chore: leave changelog to release prep
2026-07-20 14:34:05 +10:00
Yiğit ERDOĞAN
ee37c840f3 fix(reef): contain startup friend reconcile failures (#110918)
* fix(reef): contain startup friend reconcile failures

The periodic reconcile treats a transient relay failure as non-fatal, but
the startup reconcile was a bare await outside the lifecycle. A relay 429
there rejects startAccount, and the supervisor restart that follows is
itself what escalates relay rate limiting -- so Reef gives up permanently
after MAX_RESTARTS while the relay is still throttling.

Move the startup reconcile into runReefChannelLifecycle so both paths
share one failure policy, and activate through an onReady hook to preserve
the existing ordering: refresh peer keys, activate, then start the inbox.

* fix(reef): harden reconcile recovery

Co-authored-by: Yigtwxx <yigiterdogan023@gmail.com>

* docs(changelog): credit Reef reconcile fix

* test(reef): satisfy exact-head validation

* test(reef): satisfy lint contract

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-18 23:18:20 +01:00
Peter Steinberger
2bcbe3a612 feat(reef): follow up on unconfirmed deliveries instead of staying silent (#110938)
* feat(reef): follow up on unconfirmed deliveries instead of staying silent

* test(reef): satisfy lint and test-type gates for delivery notices

* test(reef): keep rejection notifier mock signature untyped
2026-07-18 21:08:10 +01:00
Peter Steinberger
e80b0b5aa5 fix(reef): stop leaking the inbox loop across channel crash restarts (#110870)
* fix(reef): stop leaking the inbox loop across channel crash restarts

* fix(reef): move channel lifecycle helper to its own module for lint/deadcode gates
2026-07-18 19:59:58 +01:00
cxbAsDev
af2662f25a fix(reef): add timeout and bounded JSON reads to relay transport (#108333)
* fix(reef): bound relay request duration

Co-authored-by: 陈宪彪0668000387 <chen.xianbiao@xydigit.com>

* test(reef): satisfy timeout fixture lint

Co-authored-by: 陈宪彪0668000387 <chen.xianbiao@xydigit.com>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: Peter Steinberger <peter@steipete.me>
2026-07-18 13:28:32 +01:00
Peter Steinberger
0546e15c2e fix(reef): omit absent receipt categories from audit state (#110177) 2026-07-17 22:24:33 +01:00
Peter Steinberger
9f8550e8b7 fix(reef): restore inbox recovery after gateway restart (#110100)
* fix(reef): persist inbox recovery progress

* chore(reef): leave changelog to release flow

* fix(reef): keep inbox recovery internals private

* fix(reef): reset healthy reconnect backoff

* chore(reef): remove stale lint suppression
2026-07-17 20:32:17 +01:00
Peter Steinberger
8020dd3e08 fix(reef): discover trusted peers as conversations (#109905)
* fix(reef): discover trusted peer conversations

* test(reef): document temporary state cleanup

* test(gateway): include conversation discovery in method order

* chore: leave changelog to release automation

* fix(gateway): preserve configured conversation discovery

* fix(gateway): validate turns before session binding

* fix(gateway): preserve directory conversation identity
2026-07-17 13:55:30 +01:00
Wynne668
708d2020d8 fix(reef): prevent blank guard keys from denying every message (#109667)
* fix(reef): reject blank guard credentials

* fix(reef): type fetch mock in guard credential test

Co-authored-by: Cursor <cursoragent@cursor.com>

* refactor: normalize Reef guard credentials canonically

Co-authored-by: ZengWen-DT <ceng.wen@xydigit.com>

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-17 10:19:21 +01:00
Peter Steinberger
0e792b6de3 refactor(channels): centralize inbound orchestration and remove internal compat (#109716)
* refactor(channels): centralize inbound turn orchestration

* refactor(runtime): remove stale compatibility paths

* chore(guards): reject internal deprecated API use

* refactor(channels): simplify core turn planning

* chore(guards): keep deprecated checks boundary-focused

* refactor(memory): keep modern config off compat barrel

* fix(msteams): preserve feedback learning

* test(channels): align modern inbound fixtures

* refactor(channels): finish modern inbound migration

* refactor(channels): tighten core inbound kernel

* fix(channels): preserve turn assembly narrowing

* test(sdk): keep runtime mock binding immutable

* test(matrix): isolate read policy runtime

* test(msteams): mock canonical reply factory

* test(slack): mock core inbound turn dispatch

* test(telegram): inject core session recorder

* test(signal): inject core session recorder

* test(googlechat): assert canonical inbound routing

* test(synology-chat): align core turn fixture

* fix(sdk): preserve direct DM runtime compat

* refactor(channels): own inbound envelope compat in core

* refactor(channels): trim inbound dispatch seams

* refactor(channels): remove redundant async wrappers

* test(synology-chat): type canonical dispatcher mock

* refactor(channels): remove remaining dead compat seams

* chore(sdk): refresh API baseline after rebase

* fix(channels): preserve direct DM identity metadata
2026-07-17 00:56:46 -07:00
Peter Steinberger
a2ec3f6904 refactor: separate external conversations from local sessions (#109411)
* feat: separate external conversations from sessions

* test: cover conversation tool authorization

* chore: refresh session schema baseline

* fix: persist effective conversation delivery text

* fix: bind conversation identity to delivery target

* fix: preserve pending conversation deliveries

* fix: make conversation delivery outcomes synchronous

* refactor: make conversation delivery durable

* fix: harden durable conversation retries

* fix: close durable conversation pre-send gaps

* fix: terminally reject invalid conversation deliveries

* refactor: route external conversations through gateway

* fix: namespace conversation delivery queue intents

* refactor: remove obsolete transcript replacement path

* test: prove conversation delivery v10 migration

* test: keep conversation action mock typed

* fix: clear conversation refactor CI gates

* test: align Reef delivery coverage

* chore: refresh Android conversation strings

* fix: harden external conversation state

* fix: close conversation race edges

* fix: preserve conversation delivery identity

* fix: replay durable conversation operations

* fix: unify agent schema at version 11

* chore: move release note context to PR

* fix: make required queue persistence force core delivery

* chore: refresh plugin SDK baseline
2026-07-17 00:09:51 -07:00
Peter Steinberger
83d82c9302 refactor(channels): persist runtime state in plugin SQLite (#109380)
* refactor(channels): move reef, msteams, matrix, zalouser file state to SQLite with doctor imports

* fix(channels): harden SQLite state migrations

* test(reef): use SQLite flow stores in receipt suites

* fix(reef): validate restored request policy

* fix(reef): retain replay state through relay window

* docs(reef): describe durable state import

* fix(reef): honor configured legacy state path

* chore: leave changelog to release flow

* fix(reef): use managed temp root in flow tests

* fix(matrix): omit undefined device id from state
2026-07-16 17:05:28 -07:00
xingzhou
2cd236385b fix(reef): close provider streams after guard errors (#109196) 2026-07-16 15:53:23 -07:00
Peter Steinberger
39cddf847e fix(reef): keep routine agent replies from disappearing (#109160)
* fix(reef): relax guard and surface rejections

* fix(reef): preserve ordered rejection notices

* fix(reef): bound rejection notice retries

* fix(reef): persist correlated rejection notices

* fix(reef): align receipt entry typing

* test(reef): type owner notice fixtures

* fix(reef): make rejection feedback restart-safe

* fix(reef): retry rejection state reads

* fix(reef): quarantine invalid receipts

* chore(reef): leave changelog to release

* fix(reef): bind receipts to recipient identity

* refactor(reef): keep receipt types private

* test(reef): preserve notice mock call typing

* fix(reef): reconcile keys before resend recovery

* fix(reef): keep rejection recovery durable

* fix(reef): preserve in-flight receipt upgrades

* test(reef): split receipt flow coverage

* fix(reef): cap automatic guard retries
2026-07-16 12:36:22 -07:00
Sally O'Malley
11c7360af5 fix(chat): keep internal metadata out of transcripts (#109056)
* fix(chat): keep internal metadata out of transcripts

Signed-off-by: sallyom <somalley@redhat.com>

* fix(gateway): harden control reply projection

Co-authored-by: sallyom <somalley@redhat.com>

* chore: leave changelog to release tooling

---------

Signed-off-by: sallyom <somalley@redhat.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 10:47:43 -07:00
pick-cat
419c61a590 fix(reef): add WebSocket handshake timeout to inbox connection (#109052)
* fix(reef): add WebSocket handshake timeout to inbox connection

Stalled Reef relay TCP peers that never complete the HTTP upgrade could
hang createReefWebSocket forever. Bound the handshake at 30s like sibling
channel WebSocket clients.

Co-authored-by: Cursor <cursoragent@cursor.com>

* test(reef): prove inbox WebSocket handshake timeout on never-upgrade peer

Co-authored-by: Cursor <cursoragent@cursor.com>

* chore(ci): retrigger checks after OpenGrep install flake

Co-authored-by: Cursor <cursoragent@cursor.com>

* test(reef): simplify handshake timeout proof

Co-authored-by: Pick-cat <huang.ting3@xydigit.com>

* style(reef): satisfy promise executor lint

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 10:29:01 -07:00
Peter Steinberger
f89c624ebb fix(reef): bound inbox WebSocket frames (#108886) 2026-07-16 03:17:52 -07:00
pick-cat
9026b9f4ac fix(reef): bound relay HTTP JSON response body reads (#106456)
* fix(reef): bound relay HTTP JSON response body reads

* test(reef): cover relay response boundaries

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 01:00:35 -07:00
Peter Steinberger
ff4d854167 fix(reef): migrate legacy peer trust config (#108417)
* fix(reef): migrate legacy peer trust config

* chore(reef): leave changelog to release flow

* build(reef): refresh bundled config metadata

* fix(reef): keep identity scope internal
2026-07-15 11:37:32 -07:00
Peter Steinberger
f810fb35d5 refactor(reef): centralize peer trust in SQLite (#108375)
* feat(plugin-sdk): support removing pairing requests

* refactor(reef): centralize peer trust in SQLite

* chore: defer Reef release note

* fix(reef): share runtime state across module instances

* refactor(reef): narrow trust store boundary

* test(reef): pass config to account description
2026-07-15 10:21:54 -07:00
Peter Steinberger
243eecbee1 refactor(reef): use Noble byte utilities 2026-07-14 14:20:59 -07:00
Peter Steinberger
c56d1bbbbb fix(reef): send through the connected gateway (#107373)
* fix(reef): route outbound through gateway

* chore: keep Reef release note in PR
2026-07-14 04:08:36 -07:00
sunlit-deng
7aa1aacb8e fix(reef): prevent oversized guard responses from consuming memory (#106439)
* fix(reef): bound guard provider response reads

* test(reef): strengthen guard response bound proof

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-13 18:02:11 -07:00
Peter Steinberger
d361b4ccb8 feat(reef): headless openclaw reef CLI for agent-driven registration and pairing
Adds a non-interactive command surface (openclaw reef register|status|friend code|request|list|remove) so an agent can claim a handle and manage guarded friendships when its owner asks, without the interactive wizard. --json emits machine-readable output for automation. Registration is crash-safe and idempotent: guard defaults are provider-coupled, the full config is validated before the single-use magic-link token is consumed, a duplicate-handle claim recovers by proving key ownership and reconciling the relay's request policy, the exchanged session is cached scoped to relay+email (never printed) so reruns recover, one state dir is pinned to one identity, and friend removal revokes both the pin and the allowlist entry. Manifest gains commandAliases/onCommands so the CLI resolves; docs cover the agent-driven path.
2026-07-13 16:23:13 -07:00
Peter Steinberger
6315dd8e2d fix(reef): adopt self-initiated friendships via durable outbound-intent markers 2026-07-13 13:03:55 -07:00
Peter Steinberger
2d5803a250 fix(reef): use bundled-channel-entry contract so channelConfigs surfaces load 2026-07-13 08:52:14 -07:00
Peter Steinberger
882b2fe900 feat(channels): bundle Reef guarded claw-to-claw channel (#106232)
* feat(channels): bundle Reef guarded claw-to-claw channel

Moves the Reef channel extension from openclaw/reef into the bundled extensions tree with the wire protocol vendored under extensions/reef/protocol. Includes channelConfigs manifest metadata, runtime status reporting via setStatus/buildAccountSnapshot, abort-aware inbox shutdown, monotonic device-auth timestamps, and immutable-model guard admission (dated snapshots plus documented gpt-5.6 ids).

* fix(reef): pin zod exactly per dependency pin guard

* style(reef): satisfy extension lint gates

Curly braces in vendored protocol, explicit type re-exports, typed catch callbacks, Object.assign over map-spread, abort-aware loop restructure.

* fix(reef): CI gates — knip workspace, boundary tsconfig, facade imports, cycle break, contract baselines

- knip: reef workspace project includes vendored protocol/ (owns noble deps)
- tsconfig: conform to canonical extension package-boundary include/exclude; add @openclaw/plugin-sdk devDependency
- imports: channel-inbound/channel-outbound facades instead of deprecated subpaths
- protocol: home ReplayStore contract in envelope.ts to break the envelope<->replay type cycle
- baselines: reef in unguarded runtime-api list; regenerate bundled channel config metadata

* feat(reef): plugin catalog cover art, channel label, changelog revert

* fix(reef): drop unused error-class exports, register lint suppression

* fix(reef): knip entry surface for vendored protocol, explicit WebSocketLike export
2026-07-13 05:17:44 -07:00